[ZOJ3899]State Reversing
阿新 • • 發佈:2018-04-20
cpp std lin down ems 直接 wap += 16px
題意:有$N$個互不相同的物品和$M$個房間,初始時每個房間都可用,有$D$次修改$(l,r)$,表示將第$l$個房間到第$r$個房間的狀態翻轉(可用$\Leftrightarrow$不可用),並詢問把物品放到房間(不能有空房,房間視作相同的)的方案數
之前鴿了,今天去ZOJ看發現居然是車萬題,有奇妙的感覺
直接用線段樹維護,答案是第二類斯特林數,預處理一下就好了,原根應該是只能暴力求的==
紫媽
#include<stdio.h> #include<string.h> typedef long long ll; const int mod=880803841;//g=26 int mul(int a,int b){return a*(ll)b%mod;} int ad(int a,int b){return(a+b)%mod;} int de(int a,int b){return(a-b)%mod;} int pow(int a,int b){ int s=1; while(b){ if(b&1)s=mul(s,a); a=mul(a,a); b>>=1; } return s; } int rev[262144],N,iN; void pre(int n){ int i,k; for(N=1,k=0;N<n;N<<=1)k++; for(i=0;i<N;i++)rev[i]=(rev[i>>1]>>1)|((i&1)<<(k-1)); iN=pow(N,mod-2); } void swap(int&a,int&b){a^=b^=a^=b;} void ntt(int*a,int on){ int i,j,k,t,w,wn; for(i=0;i<N;i++){ if(i<rev[i])swap(a[i],a[rev[i]]); } for(i=2;i<=N;i<<=1){ wn=pow(26,(on==1)?(mod-1)/i:(mod-1-(mod-1)/i)); for(j=0;j<N;j+=i){ w=1; for(k=0;k<i>>1;k++){ t=mul(w,a[i/2+j+k]); a[i/2+j+k]=de(a[j+k],t); a[j+k]=ad(a[j+k],t); w=mul(w,wn); } } } if(on==-1){ for(i=0;i<N;i++)a[i]=mul(a[i],iN); } } int s[400010],r[400010]; void build(int l,int r,int x){ ::r[x]=0; s[x]=r-l+1; if(l==r)return; int mid=(l+r)>>1; build(l,mid,x<<1); build(mid+1,r,x<<1|1); } void pushup(int x){s[x]=s[x<<1]+s[x<<1|1];} void gao(int x,int len){ r[x]^=1; s[x]=len-s[x]; } void pushdown(int x,int ln,int rn){ if(r[x]){ gao(x<<1,ln); gao(x<<1|1,rn); r[x]=0; } } void modify(int L,int R,int l,int r,int x){ if(L<=l&&r<=R)return gao(x,r-l+1); int mid=(l+r)>>1; pushdown(x,mid-l+1,r-mid); if(L<=mid)modify(L,R,l,mid,x<<1); if(mid<R)modify(L,R,mid+1,r,x<<1|1); pushup(x); } int a[262144],b[262144],fac[100010],rfac[100010]; int main(){ int T,n,m,q,i,l,r; fac[0]=1; for(i=1;i<=100000;i++)fac[i]=mul(fac[i-1],i); rfac[100000]=pow(fac[100000],mod-2); for(i=100000;i>0;i--)rfac[i-1]=mul(rfac[i],i); scanf("%d",&T); while(T--){ scanf("%d%d%d",&m,&n,&q); memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); build(1,n,1); pre((m+1)<<1|1); for(i=0;i<=m;i++){ a[i]=(i&1?-1:1)*rfac[i]; b[i]=mul(pow(i,m),rfac[i]); } ntt(a,1); ntt(b,1); for(i=0;i<N;i++)a[i]=mul(a[i],b[i]); ntt(a,-1); for(i=m+1;i<N;i++)a[i]=0; while(q--){ scanf("%d%d",&l,&r); modify(l,r,1,n,1); if(s[1]>m) puts("0"); else printf("%d\n",(a[s[1]]+mod)%mod); } } }
[ZOJ3899]State Reversing