[模板]多项式封装(无讲解)

  1 // luogu-judger-enable-o2
  2 #include<bits/stdc++.h>
  3 #define mod 998244353
  4 #define G 3
  5 #define Gi 332748118
  6 using namespace std;
  7 typedef long long int ll;
  8 typedef long double ld;
  9 const int maxn=4E5+5;
 10 const double pi=std::acos(-1);
 11 const ll K=32768;
 12 
 13 ll n,a[maxn*2],wait[maxn*2],wait_val[maxn*2];
 14 ll poly_A[maxn*2],poly_B[maxn*2];
 15 
 16 int r[maxn*2];
 17 template<class T>inline void copy(T*A,T*B,int n)
 18 {
 19     for(int i=0;i<=n;++i)
 20         A[i]=B[i];
 21 }
 22 inline ll qpow(ll x,ll y)
 23 {
 24     ll ans=1,base=x;
 25     while(y)
 26     {
 27         if(y&1)
 28             ans=ans*base%mod;
 29         base=base*base%mod;
 30         y>>=1;
 31     }
 32     return ans;
 33 }
 34 struct poly
 35 {
 36     ll*f;
 37     int n;
 38     poly(int x)
 39     {
 40         n=x;
 41         f=new ll[n+1];
 42         for(int i=0;i<=n;++i)
 43             f[i]=0;
 44     }
 45     template<class T>poly(int x,T*A)
 46     {
 47         n=x;
 48         f=new ll[n+1];
 49         for(int i=0;i<=n;++i)
 50             wait_val[i]=A[i];
 51         for(int i=0;i<=n;++i)
 52             f[i]=wait_val[i];
 53     }
 54     void change(int x,bool keep=1)
 55     {
 56         if(keep)
 57             for(int i=0;i<=n;++i)
 58                 wait[i]=f[i];
 59         delete f;
 60         f=new ll[x+1];
 61         for(int i=0;i<=x;++i)
 62             f[i]=0;
 63         if(keep)
 64             for(int i=0;i<=min(n,x);++i)
 65                 f[i]=wait[i];
 66         n=x;
 67     }
 68     void DFT(int len,int sign,ll*g)
 69     {
 70         copy(wait,f,1<<len);
 71         for(int i=0;i<(1<<len);++i)
 72         {
 73             r[i]=(r[i>>1]>>1)|(i&1?1<<(len-1):0);
 74             if(i<r[i])
 75                 swap(wait[i],wait[r[i]]);
 76         }
 77         for(int i=2;i<=(1<<len);i<<=1)
 78         {
 79             ll d;
 80             if(sign==1)
 81                 d=qpow(G,(mod-1)/i);
 82             else
 83                 d=qpow(Gi,(mod-1)/i);
 84             for(int j=0;j<(1<<len)/i;++j)
 85             {
 86                 ll w=1;
 87                 for(int k=0;k<i/2;++k)
 88                 {
 89                     ll a=wait[j*i+k],b=wait[j*i+k+i/2]*w%mod;
 90                     wait[j*i+k]=(a+b)%mod;
 91                     wait[j*i+k+i/2]=(a-b+mod)%mod;
 92                     w=w*d%mod;
 93                 }
 94             }
 95         }
 96         copy(g,wait,1<<len);
 97     }
 98     void integral()
 99     {
100         change(n+1);
101         for(int i=n;i>=1;--i)
102             f[i]=f[i-1]*qpow(i,mod-2)%mod;
103         f[0]=0;
104     }
105     void differential()
106     {
107         for(int i=0;i<n;++i)
108             f[i]=(i+1)*f[i+1]%mod;
109         f[n]=0;
110     }
111     void out()
112     {
113         for(int i=0;i<=n;++i)
114             cout<<f[i]<<" ";
115         cout<<endl;
116     }
117 };
118 template<class T>static void FFT(poly&A,poly&B,T*to,bool show=0)
119 {
120     int len=0,s=A.n+B.n,Bn=B.n;
121     while((1<<len)<=A.n+B.n+1)
122         ++len;
123     int limit=1<<len;
124     if(show)
125         cout<<"NOW"<<len<<" "<<limit<<endl;
126     if(show)
127         cout<<"--------------------"<<endl;
128     A.change(limit);
129     B.change(limit);
130     if(show)
131         A.out(),B.out();
132     if(show)
133         cout<<"--------------------"<<endl;
134     A.DFT(len,1,A.f);
135     B.DFT(len,1,poly_B);
136     for(int i=0;i<limit;++i)
137         A.f[i]=A.f[i]*poly_B[i];
138     A.DFT(len,-1,A.f);
139     ll g=qpow(limit,mod-2);
140     for(int i=0;i<limit;++i)
141         to[i]=A.f[i]=A.f[i]*g%mod;
142     A.change(s);
143     B.change(Bn);
144 }
145 static void polyInv(const poly&A,poly&P,int now)
146 {
147     if(now==0)
148     {
149         P.f[0]=qpow(A.f[0],mod-2);
150         return;
151     }
152     polyInv(A,P,now>>1);
153     poly B(now,A.f),B_(now>>1,P.f);
154     FFT(B,B_,wait);
155     B.change(now);
156     FFT(B,B_,wait);
157     for(int i=0;i<=now>>1;++i)
158         P.f[i]=(2*P.f[i]-B.f[i]+mod)%mod;
159     for(int i=(now>>1)+1;i<=now;++i)
160         P.f[i]=(mod-B.f[i])%mod;
161 }
162 static void polyIn(poly&P)
163 {
164     poly A(P.n,P.f),B(P.n);
165     A.differential();
166     polyInv(P,B,P.n);
167     FFT(B,A,wait);
168     P=B;
169     P.integral();
170     P.change(A.n);
171 }
172 static void polyExp(const poly&A,poly&P,int now)
173 {
174     if(now==0)
175     {
176         P.f[0]=1;
177         return;
178     }
179     polyExp(A,P,now>>1);
180     poly F(now,P.f),H(now,P.f);
181     for(int i=P.n+1;i<=now;++i)
182         F.f[i]=H.f[i]=0;
183     polyIn(H);
184     for(int i=0;i<=now;++i)
185         H.f[i]=((i==0)-H.f[i]+A.f[i]+mod)%mod;
186     FFT(H,F,wait);
187     P.change(now);
188     copy(P.f,H.f,now);
189 }
190 static void polySqrt(poly&P)
191 {
192     polyIn(P);
193     ll g=qpow(2,mod-2);
194     for(int i=0;i<=P.n;++i)
195         P.f[i]=P.f[i]*g%mod;
196     poly A(P.n,wait);
197     polyExp(P,A,P.n);
198     copy(P.f,A.f,P.n);
199 }
200 static void polyPow(poly&P,ll k)
201 {
202     polyIn(P);
203     for(int i=0;i<=P.n;++i)
204         P.f[i]=P.f[i]*k%mod;
205     poly A(P.n,wait);
206     polyExp(P,A,P.n);
207     copy(P.f,A.f,P.n);
208 }
209 int main()
210 {
211     ios::sync_with_stdio(false);
212     string str;
213     ll k=0;
214     cin>>n>>str;
215     for(int i=0;i<str.size();++i)
216         k=(k*10+str[i]-'0')%mod;
217     --n;
218     for(int i=0;i<=n;++i)
219         cin>>a[i];
220     poly A(n,a);
221     polyPow(A,k);
222     A.out();
223     return 0;
224 }
View Code
原文地址:https://www.cnblogs.com/GreenDuck/p/11175534.html