cf 632E FFT+快速幂
Posted nervendnig
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了cf 632E FFT+快速幂相关的知识,希望对你有一定的参考价值。
fft+快速幂,需要不少优化才能过
#include<bits/stdc++.h> #define ll long long #define rep(ii,a,b) for(int ii=a;ii<=b;++ii) #define per(ii,a,b) for(int ii=b;ii>=a;--ii) #define forn(i,x,g,e) for(int i=g[x];i;i=e[i].next) #define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0) #define ull unsigned long long #define fi first #define se second #define mp make_pair #define pii pair<ll,ll> #define all(x) x.begin(),x.end() #define show(x) cout<<#x<<"="<<x<<endl #define showa(a,b) cout<<#a<<‘[‘<<b<<"]="<<a[b]<<endl #define show2(x,y) cout<<#x<<"="<<x<<" "<<#y<<"="<<y<<endl #define show3(x,y,z) cout<<#x<<"="<<x<<" "<<#y<<"="<<y<<" "<<#z<<"="<<z<<endl #define show4(w,x,y,z) cout<<#w<<"="<<w<<" "<<#x<<"="<<x<<" "<<#y<<"="<<y<<" "<<#z<<"="<<z<<endl #define show5(v,w,x,y,z) cout<<#v<<"="<<v<<" "<<#w<<"="<<w<<" "<<#x<<"="<<x<<" "<<#y<<"="<<y<<" "<<#z<<"="<<z<<endl #define showa2(x,a,b) cout<<#x<<": ";rep(i,a,b) cout<<x[i]<<‘ ‘;cout<<endl using namespace std; int n,k; const double pi=acos(-1.0); struct cpdouble x,y;; inline cp operator*(cp a,cp b)return a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x; inline cp operator+(cp a,cp b)return a.x+b.x,a.y+b.y; inline cp operator-(cp a,cp b)return a.x-b.x,a.y-b.y; const int maxl=1e6+10; int la,lb; bool a[maxl<<2]; bool ret[maxl<<2]; class fourierpublic: int rev[maxl<<2],len,pw; void init(int n) len=1,pw=0; while(len<=n) len<<=1,pw++; rep(i,0,len-1) rev[i]=0; rep(i,0,len-1) rev[i]=(rev[i>>1]>>1)|((i&1)<<(pw-1)); cp c1[maxl<<2],c2[maxl<<2]; cp wt[maxl<<2]; void init_0(int ml=maxl) for(int mid=1;mid<2*maxl;mid<<=1) // wt.resize(mid*2+1); cp wn1=cos(pi/mid),sin(pi/mid); wt[mid]=(cp)1,0; rep(j,1,mid-1) wt[mid+j]=wt[mid+j-1]*wn1; void transform(cp*a,int flag) rep(i,0,len-1) if(i<rev[i]) swap(a[i],a[rev[i]]); for(int mid=1;mid<len;mid<<=1) for(int r=mid<<1,j=0;j<len;j+=r) for(int k=0;k<mid;++k) cp wn=wt[mid+k]; if(flag==-1) wn.y=-wn.y; cp y=wn*a[mid+j+k]; a[j+k+mid]=a[j+k]-y,a[j+k]=a[j+k]+y; if(flag==-1) rep(i,0,len-1) a[i].x/=len; void fix1()while(la&&!ret[la-1])--la; void fix2()while(lb&&!a[lb-1])--lb; //@传入整数,进行卷积@ void mul(bool *a,bool *b) init(la+lb); rep(i,0,la-1)c1[i].x=a[i],c1[i].y=0; rep(i,la,len-1)c1[i].x=c1[i].y=0; rep(i,0,lb-1)c2[i].x=b[i],c2[i].y=0; rep(i,lb,len-1)c2[i].x=c2[i].y=0; transform(c1,1);transform(c2,1); rep(i,0,len-1) c1[i]=c1[i]*c2[i]; transform(c1,-1); la=len; rep(i,0,len-1) a[i]=c1[i].x>=0.5; fix1(); void sqr(bool *a) init(2*lb); rep(i,0,lb-1)c1[i].x=a[i],c1[i].y=0; rep(i,lb,len-1)c1[i].x=c1[i].y=0; transform(c1,1); rep(i,0,len-1) c1[i]=c1[i]*c1[i]; transform(c1,-1); lb=len; rep(i,0,len-1) a[i]=c1[i].x>=0.5; fix2(); void pow(int k) fix1();la=1,ret[0]=1; while(k) if(k&1) mul(ret,a); sqr(a); k>>=1; fft; int s[2000]; int main() ios::sync_with_stdio(false);cin.tie(0); cin>>n>>k; for(int i=1;i<=n;i++) cin>>s[i]; a[s[i]]=1; sort(s+1,s+1+n); fft.init_0(s[n]*k+1); lb=1001; fft.pow(k); int len=min(la,s[n]*k+1); for(int i=k;i<len;i++) if(ret[i]) cout<<i<<" ";
以上是关于cf 632E FFT+快速幂的主要内容,如果未能解决你的问题,请参考以下文章
BZOJ 4332 4332: JSOI2012 分零食 (FFT+快速幂)