SDOI2018:原题识别
题解:
https://files.cnblogs.com/files/clrs97/old-solution.pdf
Code:
#include<cstdio> #include<cstdlib> #include<algorithm> using namespace std; typedef long long ll; const int N=100010,M=1010,E=5500000,BUF=10000000,OUT=10000000; unsigned int SA,SB,SC; int Case,n,p,m,lim,X,i,j,k,op,x,y,a[N],g[N],nxt[N],st[N],en[N],dfn,s[N<<1],q[N]; int b[M],cb,f[M][M],ga[N<<1],gq[N<<1],vl[E],vr[E],w[E],NXT[E],ED; ll ans[N<<1],bit[N<<1],bitx[N<<1],bity[N<<1],bitxy[N<<1]; char Buf[BUF],*buf=Buf,Out[OUT],*ou=Out;int Outn[30],Outcnt; inline void read(int&a){for(a=0;*buf<48;buf++);while(*buf>47)a=a*10+*buf++-48;} inline void read(unsigned int&a){for(a=0;*buf<48;buf++);while(*buf>47)a=a*10+*buf++-48;} inline void write(ll x){ if(!x)*ou++=48; else{ for(Outcnt=0;x;x/=10)Outn[++Outcnt]=x%10+48; while(Outcnt)*ou++=Outn[Outcnt--]; } } inline void writeln(ll x){write(x);*ou++='\n';} inline unsigned int rng61(){ SA^=SA<<16; SA^=SA>>5; SA^=SA<<1; unsigned int t=SA; SA=SB; SB=SC; SC^=t^SA; return SC; } inline void addedge(int x,int y){nxt[y]=g[x];g[x]=y;} inline void add(int&x,int l,int r,int z){vl[++ED]=l;vr[ED]=r;w[ED]=z;NXT[ED]=x;x=ED;} void dfs(int x){ lim=st[x]=++dfn; s[dfn]=1; for(int i=g[x];i;i=nxt[i])dfs(i); en[x]=++dfn; s[dfn]=-1; } inline bool cmp(int x,int y){return a[x]<a[y];} inline void initrect(){ int _=0,i,j; sort(b+1,b+cb+1); for(i=1;i<=cb;i++)if(b[i]!=b[i-1])b[++_]=b[i]; cb=_; for(i=1;i<=cb;i++)for(j=1;j<=cb;j++)f[i][j]=0; } inline void maketag(int xl,int xr,int yl,int yr,int p){ xl=lower_bound(b,b+cb+1,xl-1)-b+1; xr=lower_bound(b,b+cb+1,xr)-b+1; yl=lower_bound(b,b+cb+1,yl-1)-b+1; yr=lower_bound(b,b+cb+1,yr)-b+1; f[xl][yl]+=p; f[xl][yr]-=p; f[xr][yl]-=p; f[xr][yr]+=p; } inline void getrect(){ int i,j; for(i=1;i<=cb;i++)for(j=1;j<=cb;j++){ f[i][j]+=f[i-1][j]+f[i][j-1]-f[i-1][j-1]; if(f[i][j]){ add(ga[b[i-1]+1],b[j-1]+1,b[j],1); add(ga[b[i]+1],b[j-1]+1,b[j],-1); } } } inline void solve(int x,int mode){ if(mode==0){ b[++cb]=st[x]-1; b[++cb]=en[x]; for(int i=g[x];i;i=nxt[i]){ b[++cb]=st[i]-1; b[++cb]=en[i]; } }else{ maketag(st[x],en[x],1,lim,1); maketag(1,lim,st[x],en[x],1); for(int i=g[x];i;i=nxt[i])maketag(st[i],en[i],st[i],en[i],-2); } } inline void ins(int y,int p){ ll B=1LL*s[X-1]*p,C=1LL*s[y-1]*p,D=1LL*s[X-1]*s[y-1]*p; for(;y<=lim;y+=y&-y){ bit[y]+=p; bitx[y]+=B; bity[y]+=C; bitxy[y]+=D; } } inline ll ask(int y){ ll A=0,B=0,C=0,D=0;int o=y; for(;y;y-=y&-y){ A+=bit[y]; B+=bitx[y]; C+=bity[y]; D+=bitxy[y]; } return A*s[X]*s[o]-B*s[o]-C*s[X]+D; } void work(){ read(n),read(p),read(SA),read(SB),read(SC); for(i=1;i<=n;i++)g[i]=0; for(i=1;i<=n+n;i++)ga[i]=gq[i]=bit[i]=bitx[i]=bity[i]=bitxy[i]=0; dfn=ED=0; for(i=2;i<=p;i++)addedge(i-1,i); for(i=p+1;i<=n;i++)addedge(rng61()%(i-1)+1,i); for(i=1;i<=n;i++)a[i]=rng61()%n+1; dfs(1); for(i=1;i<=lim;i++)s[i]+=s[i-1]; for(i=1;i<=n;i++){ q[i]=i; if(en[i]>lim)en[i]=lim; } sort(q+1,q+n+1,cmp); for(i=1;i<=n;i=j){ b[0]=0; b[cb=1]=lim; for(j=i;j<=n&&a[q[i]]==a[q[j]];j++)solve(q[j],0); initrect(); for(k=i;k<j;k++)solve(q[k],1); getrect(); } read(m); for(i=1;i<=m;i++){ read(op),read(x),read(y); ans[i]=0; int xl,xr,yl,yr; if(op==1){ xl=xr=st[x]; yl=yr=st[y]; }else{ xl=1,xr=st[x]; yl=1,yr=st[y]; } add(gq[xl-1],yl,yr,-i); add(gq[xr],yl,yr,i); } for(X=1;X<=lim;X++){ for(j=ga[X];j;j=NXT[j]){ ins(vl[j],w[j]); ins(vr[j]+1,-w[j]); } for(j=gq[X];j;j=NXT[j]){ k=w[j]; if(k>0)ans[k]+=ask(vr[j])-ask(vl[j]-1); else ans[-k]-=ask(vr[j])-ask(vl[j]-1); } } for(i=1;i<=m;i++)writeln(ans[i]); } int main(){ fread(Buf,1,BUF,stdin); read(Case); while(Case--)work(); fwrite(Out,1,ou-Out,stdout); return 0; }