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(ai−aj)。
然后每次枚举答案 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
leetcode 209. Minimum Size Subarray Sum