B - Minimum Modula (暴力&剪枝)

Posted Harris-H

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了B - Minimum Modula (暴力&剪枝)相关的知识,希望对你有一定的参考价值。

B - Minimum Modular (暴力&剪枝)

先枚举答案,显然暴力 O ( n m ) O(nm) O(nm)不行。

考虑剪枝,预处理任意两数 a b s ( a i − a j ) abs(a_i-a_j) abs(aiaj)

然后每次枚举答案 x x x,计算出所有差值为 x x x的倍数的个数。

显然如果个数 c n t > k ( k + 1 ) 2 cnt>\\dfrac{k(k+1)}{2} cnt>2k(k+1),显然是不行的。

因为最多删 k k k个数,如果 c n t > k ( k + 1 ) 2 cnt>\\dfrac{k(k+1)}{2} cnt>2k(k+1),说明超过 k + 1 k+1 k+1个数了。

因为 k k k很小,所以剪枝后很快。

时间复杂度: O ( n 2 + m l o g m ) O(n^2+mlogm) O(n2+mlogm)

// Problem: CF303C Minimum Modular
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/CF303C
// Memory Limit: 250 MB
// Time Limit: 2000 ms
// Date: 2021-09-16 10:58:41
// --------by Herio--------

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull; 
const int N=5e3+5,M=1e6+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a,b) memset(a,b,sizeof a)
#define PII pair<int,int>
#define x first
#define y second
#define pb emplace_back
#define SZ(a) (int)a.size()
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define per(i,a,b) for(int i=a;i>=b;--i)
#define ios ios::sync_with_stdio(false),cin.tie(0) 
void Print(int *a,int n){
	for(int i=1;i<n;i++)
		printf("%d ",a[i]);
	printf("%d\\n",a[n]); 
}
int n,k;
int a[N],b[M],vis[M];
int main(){
	scanf("%d%d",&n,&k);
	rep(i,1,n) scanf("%d",&a[i]);sort(a+1,a+n+1);
	rep(i,1,n)
		rep(j,i+1,n) b[a[j]-a[i]]++;
	int m=a[n]+1,s=k*(k+1)>>1;
	rep(x,1,m){
		int cnt=0,sum=0;
		for(int i=x;i<=m;i+=x) cnt+=b[i];
		if(cnt>s) continue;
		rep(i,1,n)
		{
			if(vis[a[i]%x]==x) sum++;
			vis[a[i]%x]=x;
		}
		if(sum<=k) return printf("%d\\n",x),0;
	}
	return 0;
}

以上是关于B - Minimum Modula (暴力&剪枝)的主要内容,如果未能解决你的问题,请参考以下文章

51nod 1217 Minimum Modular(数论+暴力)

Minimum -depth -of -binary -tree@LeetCode

JNday4-am

leetcode 209. Minimum Size Subarray Sum

最小子串覆盖 · Minimum Window Substring

HDU 4731 Minimum palindrome 打表找规律