zoukankan      html  css  js  c++  java
  • [模板]多项式封装(无讲解)

      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
  • 相关阅读:
    单例类
    UITableView汇总
    JVM虚拟机——垃圾收集算法
    集合框架 HashMap 的扩容机制, ConcurrnetHashMap 的原理
    java判断两个单链表是否相交
    java中Comparator 和 Comparable的区别
    String getProperty(String key, String def)
    JAVA 单步调试快捷键
    Stanford Word Segmenter使用
    使用ifstream和getline读取文件内容[c++]
  • 原文地址:https://www.cnblogs.com/GreenDuck/p/11175534.html
Copyright © 2011-2022 走看看