[BZOJ3837][Pa2013][随机][乱搞]Filary

来源:互联网 发布:lte中mr优化案例 编辑:程序博客网 时间:2024/05/21 19:09

这里写图片描述
然而我太懒了……没有打哈希。
直觉告诉我第二个答案是选择的k个数的差的gcd,那么对于每一个质因数,记录一下序列中能被这个质数整除的差的gcd,然后就可以了

#include <cstdio>#include <cstdlib>#include <iostream>#include <algorithm>#define N 100010#define M 10000010using namespace std;int n,Ans1,Ans2,Maxx;int A[N],B[N];int p[M],v[M],vis[M],f[M];inline char nc(){  static char buf[100000],*p1=buf,*p2=buf;  return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;}inline void rea(int &x){  char c=nc(); x=0;  for(;c>'9'||c<'0';c=nc());for(;c>='0'&&c<='9';x=x*10+c-'0',c=nc());}inline void First(){  for(int i=2;i<=Maxx;i++){    if(!p[i]) p[++*p]=i,v[i]=*p;    for(int j=1;j<=*p&&p[j]*i<=Maxx;j++){      p[p[j]*i]=1; v[p[j]*i]=j;      if(i%p[j]==0) break;    }  }}int gcd(int x,int y){  if(!x||!y) return x+y;  return y?gcd(y,x%y):x;}int main(){  rea(n);  for(int i=1;i<=n;i++) rea(A[i]),Maxx=max(Maxx,A[i]);  First();  for(int K=1;K<=4;K++){    int x=A[rand()%n+1],cnt=0,w=0,Max=0,nAns=0;    for(int i=1;i<=n;i++)      if(A[i]!=x) B[++cnt]=A[i]<x?(x-A[i]):(A[i]-x);      else w++;    for(int i=1;i<=*p;i++) vis[i]=f[i]=0;    for(int i=1;i<=cnt;i++){      int now=B[i];      for(;now^1;now/=p[v[now]]){    vis[v[now]]++;    f[v[now]]=gcd(f[v[now]],B[i]);    int y=p[v[now]];    while((now/y)%y==0) now/=y;      }    }    for(int i=1;i<=*p;i++)      if(vis[i]>vis[Max]||(vis[i]==vis[Max]&&f[i]>nAns)) Max=i,nAns=f[i];    if(vis[Max]+w>Ans1) Ans1=vis[Max]+w,Ans2=nAns;    else if(vis[Max]+w==Ans1&&nAns>Ans2) Ans2=nAns;  }  return printf("%d %d\n",Ans1,Ans2),0;}
0 0