zoukankan      html  css  js  c++  java
  • [LOJ2541][PKUWC2018]猎人杀(容斥+分治+FFT)

    https://blog.csdn.net/Maxwei_wzj/article/details/80714129

    n个二项式相乘可以用分治+FFT的方法,使用空间回收可以只开log个数组。

     1 #include<cstdio>
     2 #include<algorithm>
     3 #define rep(i,l,r) for (int i=(l); i<=(r); i++)
     4 using namespace std;
     5 
     6 const int N=300010,mod=998244353;
     7 int n,top,ans,w[N],a[N],rev[N],S[51],tmp[51][N];
     8 
     9 int ksm(int a,int b){
    10     int res=1;
    11     for (; b; a=1ll*a*a%mod,b>>=1)
    12         if (b & 1) res=1ll*res*a%mod;
    13     return res;
    14 }
    15 
    16 void NTT(int a[],int len,int f){
    17     int n=1,L=0;
    18     for (; n<len; n<<=1) L++;
    19     for (int i=0; i<n; i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<(L-1));
    20     for (int i=0; i<n; i++) if (i<rev[i]) swap(a[i],a[rev[i]]);
    21     for (int i=1; i<n; i<<=1){
    22         int wn=ksm(3,(f==1) ? (mod-1)/(i<<1) : (mod-1)-(mod-1)/(i<<1));
    23         for (int p=i<<1,j=0; j<n; j+=p){
    24             int w=1;
    25             for (int k=0; k<i; k++,w=1ll*w*wn%mod){
    26                 int x=a[j+k],y=1ll*w*a[i+j+k]%mod;
    27                 a[j+k]=(x+y)%mod; a[i+j+k]=(x-y+mod)%mod;
    28             }
    29         }
    30     }
    31     if (f==1) return;
    32     int inv=ksm(n,mod-2);
    33     for (int i=0; i<n; i++) a[i]=1ll*a[i]*inv%mod;
    34 }
    35 
    36 int solve(int l,int r,int a[]){
    37     if (l==r){ a[0]=1; a[w[l]]=mod-1; return w[l]; }
    38     int mid=(l+r)>>1,l1,l2,ls,rs,n;
    39     ls=S[top--]; l1=solve(l,mid,tmp[ls]);
    40     rs=S[top--]; l2=solve(mid+1,r,tmp[rs]);
    41     for (n=1; n<=l1+l2; n<<=1);
    42     NTT(tmp[ls],n,1); NTT(tmp[rs],n,1);
    43     for (int i=0; i<n; i++) a[i]=1ll*tmp[ls][i]*tmp[rs][i]%mod;
    44     NTT(a,n,-1); S[++top]=ls; S[++top]=rs;
    45     for (int i=0; i<n; i++) tmp[ls][i]=tmp[rs][i]=0;
    46     return l1+l2;
    47 }
    48 
    49 int main(){
    50     freopen("kill.in","r",stdin);
    51     freopen("kill.out","w",stdout);
    52     scanf("%d",&n);
    53     rep(i,1,n) scanf("%d",&w[i]);
    54     rep(i,1,49) S[++top]=i;
    55     int len=solve(2,n,a);
    56     rep(i,0,len) ans=(ans+1ll*a[i]*ksm(w[1]+i,mod-2))%mod;
    57     printf("%lld
    ",1ll*ans*w[1]%mod);
    58     return 0;
    59 }
  • 相关阅读:
    Visual Studio 2019 Xamarin 设计器显示不正常
    Chrome 关闭稍后阅读/阅读清单功能
    Chrome 浏览器历史记录的日期格式转换 sqlite3
    将博客搬至CSDN
    python selenium 库利用 pytesseract 识别验证码方案
    layui OSS Web直传
    苹果App Store审核被拒记录(持续更新中...)
    iOS RSA加密解密
    PHP、Android、iOS接口RSA加密解密
    安卓RSA加密解密(简单复制直接使用)
  • 原文地址:https://www.cnblogs.com/HocRiser/p/10198204.html
Copyright © 2011-2022 走看看