Yet Another mod M

题目传送门

总结一下, 绝对众数 = 随机化 绝对众数=随机化 绝对众数=随机化 ,虽然这么说有点套路,但还是多这么想想

解法

如果有答案,我们随机一个数 a i a_i ai , 那么 a i a_i ai 满足 a i = x ( m o d M ) a_i =x \quad(mod \quad M) ai=x(modM) 的概率大于 50 % 50\% 50% , 所以我们随机 20 20 20 及以上次 a i a_i ai ,再随机一个 a j a_j aj 也满足条件,那么 M ∣ ( ∣ a i − a j ∣ ) M\quad|\quad(|a_i-a_j|) M(aiaj) ,对 ∣ a i − a j ∣ |a_i-a_j| aiaj 进行质因子分解即可
时间复杂度 O ( T 2 n log ⁡ n ) O(T^2n \log{n}) O(T2nlogn) , T T T 为随机的次数

Code

#include 
#include 
#include 
#include 
using namespace std;
const int N=5e3+7;

int n;
int a[N];

int main(){
    srand(10086001);
    scanf("%d",&n);
    for(int i=1;i<=n;i++) {
        scanf("%d",&a[i]);
    }
    for(int _=1;_<=52;_++) {
        int i=(rand()%n)+1;
        for(int j=1;j<=40;j++) {
            int k=(rand()%n)+1;
            int res=abs(a[i]-a[k]);
            for(int t=3;t*t<=res;t++) {
                if(res%t==0) {
                    while(res%t==0) res/=t;
                    int cnt=0;
                    if(t<=2) continue;
                    for(int l=1;l<=n;l++) {
                        if(a[l]%t==a[i]%t) {
                            cnt++;
                            if(cnt*2>n) break;
                        } 
                    }
                    if(cnt*2>n) return printf("%d\n",t),0;
                }
            }
            if(res>2) {
                int cnt=0;
                for(int l=1;l<=n;l++) {
                    if(a[l]%res==a[i]%res) {
                        cnt++;
                        if(cnt*2>n) break;
                    } 
                }
                if(cnt*2>n) return printf("%d\n",res),0;
            } 
        }
    }
    puts("-1");
}

你可能感兴趣的:(随机化)