[关闭]
@yang12138 2018-10-27T01:18:59.000000Z 字数 1912 阅读 1045

板子2


自然数幂和


时间

  1. const int N=50010;
  2. const int mod=1e9+7;
  3. ll quick_pow(ll base,ll n){
  4. ll ans=1;
  5. while(n){
  6. if(n&1) ans=ans*base%mod;
  7. base=base*base%mod;
  8. n>>=1;
  9. }
  10. return ans;
  11. }
  12. ll y[N];
  13. ll inv[N];
  14. void init(){
  15. inv[0]=1;
  16. for(int i=1;i<N;i++){
  17. inv[i]=quick_pow(i,mod-2);
  18. }
  19. }
  20. //0-n
  21. ll l[N],r[N];
  22. ll solve(int n,ll x){
  23. l[0]=x;
  24. for(int i=1;i<=n;i++) l[i]=l[i-1]*(x-i)%mod;
  25. r[n]=x-n;
  26. for(int i=n-1;i>=0;i--) r[i]=r[i+1]*(x-i)%mod;
  27. ll ans=0,cur=1;
  28. for(int i=1;i<=n;i++) (cur*=inv[i])%=mod;
  29. if(n&1) cur=-cur;
  30. for(int i=0;i<=n;i++){
  31. ll t=1;
  32. if(i>0) (t*=l[i-1])%=mod;
  33. if(i<n) (t*=r[i+1])%=mod;
  34. ans+=y[i]*t%mod*cur;
  35. ans%=mod;
  36. cur=cur*(-n+i)%mod*inv[i+1]%mod;
  37. }
  38. if(ans<0) ans+=mod;
  39. return ans;
  40. }
  41. ll s(ll n,int k){
  42. n%=mod;
  43. if(n<=k+1){
  44. ll ans=0;
  45. for(int i=1;i<=n;i++){
  46. ans+=quick_pow(i,k);
  47. if(ans>=mod) ans-=mod;
  48. }
  49. return ans;
  50. }
  51. y[0]=0;
  52. for(int i=1;i<=k+1;i++){
  53. y[i]=y[i-1]+quick_pow(i,k);
  54. if(y[i]>=mod) y[i]-=mod;
  55. }
  56. return solve(k+1,n);
  57. }

哈希求最长等差数列

数列长度在内,求能构成的长度在以上的最长的等差数列

  1. const int INF=1e9;
  2. struct HashTable{
  3. const static int N=1e5+10;
  4. const static int mod=(1<<20)+1;
  5. int val[N],nex[N],head[mod],cnt;
  6. HashTable(){cnt=0;memset(head,-1,sizeof(head));}
  7. void add(int x){
  8. int left=x%mod;
  9. val[cnt]=x,nex[cnt]=head[left],head[left]=cnt++;
  10. }
  11. bool has(int x){
  12. if(x<=0 || x>INF) return 0;
  13. for(int i=head[x%mod];~i;i=nex[i]){if(val[i]==x) return 1;}
  14. return 0;
  15. }
  16. }ht;
  17. const int N=1e5+10;
  18. int a[N];
  19. vector<int>dat[5000005];
  20. int getans(int x,int y,const int& preans){
  21. if(x==y) return 0;
  22. if(x>y) swap(x,y);
  23. int d=y-x,ans=2;
  24. if(d>5000000) return 0;
  25. for(auto i:dat[d]){if((x-i)%d==0) return 0;}
  26. while(ht.has(y+d)) ans++,y+=d;
  27. if(ans<preans){if(!ht.has(x-(preans-ans)*d)) return 0;}
  28. while(ht.has(x-d)) ans++,x-=d;
  29. if(ans>=200) dat[d].push_back(x);
  30. return ans;
  31. }
  32. void rng(int n){
  33. for(int i=1;i<=n;i++) swap(a[i],a[rand()%i+1]);
  34. }
  35. void solve(){
  36. int n;
  37. scanf("%d",&n);
  38. for(int i=1;i<=n;i++){
  39. scanf("%d",a+i);
  40. ht.add(a[i]);
  41. }
  42. rng(n);
  43. int cnt=30000000,ans=2;
  44. while(cnt--){
  45. ans=max(ans,getans(a[rand()%n+1],a[rand()%n+1],ans));
  46. }
  47. if(ans<200) printf("No Solution\n");
  48. else printf("%d\n",ans);
  49. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注