题解 P1154 【奶牛分厩】

· · 题解

注意!上一篇“飞翔”的题解有误!

首先a,b在mod k 意义下同余,当且仅当 k|(a-b) 即k是(a-b)的一个因子。

这个证明可以考虑mod运算的意义。也可以a%k=b%k 等价于 a-b=0(mod k) 。

因为s<=1e6 所以可以预处理出所有差值,并把他们打上标记。

从小到大枚举,如果一个数x未被标记,那么我们就看他的λ倍是否被标记。λ是枚举的。

如果都没被标记,则说明x是合法的。输出x即可。

关于复杂度,尽管我们枚举了k倍。但运行次数应该是s/2+s/3+s/4...+s/s 根据调和级数

这东西在OI里可以视作log级的

所以复杂度就是O(n^2+slogs) s是数域大小。

至于“飞翔”的题解,没有考虑k是a-b因子的情况。对于数据 a=16,b=6 正确应该输出3,而不是2。

为啥没有卡掉可能是数据有些水。。

codes:

#include<cstdio>
#include<cstdlib>
const int N=5e3+5,K=1e6+5;
int a[N],vis[K],n;
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;++i){
        scanf("%d",&a[i]);
    }
    for(int i=1;i<=n;++i){
        for(int j=i+1;j<=n;++j){
            int cur=abs(a[i]-a[j]);
            vis[cur]=1;
        }
    }
    for(int i=n;i<K;++i){
        if(!vis[i]){
            int f=1;
            for(int j=i;j<K;j+=i)if(vis[j]){f=0;break;}
            if(f){
                printf("%d\n",i);
                return 0;
            }
        }
    }
    return 0;
}