[SDOI2018]原题识别
题解:
。。感觉挺烦得 而且我都没有注意到树随机这件事情。。
就写个30分的莫队。。
#include <bits/stdc++.h> using namespace std; #define rint register int #define IL inline #define rep(i,h,t) for (int i=h;i<=t;i++) #define dep(i,t,h) for (int i=t;i>=h;i--) #define me(x) memset(x,0,sizeof(x)) namespace IO{ char ss[1<<24],*A=ss,*B=ss; IL char gc() { return A==B&&(B=(A=ss)+fread(ss,1,1<<24,stdin),A==B)?EOF:*A++; } template<class T>void read(T &x) { rint f=1,c; while (c=gc(),c<48||c>57) if (c=='-') f=-1; x=(c^48); while (c=gc(),c>47&&c<58) x=(x<<3)+(x<<1)+(c^48); x*=f; } char sr[1<<24],z[20]; int Z,CC=-1; template<class T>void wer(T x) { if (x<0) sr[++CC]='-',x=-x; while (z[++Z]=x%10+48,x/=10); while (sr[++CC]=z[Z],--Z); } IL void wer1() { sr[++CC]=' '; } IL void wer2() { sr[++CC]='\n'; } template<class T>IL void mina(T &x,T y) { if (x>y) x=y;} template<class T>IL void maxa(T &x,T y) { if (x<y) x=y;} template<class T>IL T MIN(T x,T y){return x<y?x:y;} template<class T>IL T MAX(T x,T y){return x>y?x:y;} }; using namespace IO; unsigned int SA, SB, SC; 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; } const int N=4.1e5; int l,head[N],n,m,c[N]; struct re{ int a,b,c,d; }e[N],a[N]; IL void arr(int x,int y) { e[++l].a=head[x]; e[l].b=y; head[x]=l; } IL void addedge(int x,int y) { arr(x,y); arr(y,x); } int p; void gen(){ cin>>n>>p>>SA>>SB>>SC; l=0; me(head); for(int i = 2; i <= p; i++) addedge(i - 1, i); for(int i = p + 1; i <= n; i++) addedge(rng61() % (i - 1) + 1, i); for(int i = 1; i <= n; i++) c[i] = rng61() % n + 1; } int cnt,dfn1[N],dfn2[N],dep[N],block,num,pos[N]; int bz[21][N],ans[N],jl[N],ans2,po[N],b[N]; void dfs(int x,int y) { bz[0][x]=y; dep[x]=dep[y]+1; dfn1[x]=++cnt; b[cnt]=x; for (rint u=head[x];u;u=e[u].a) { int v=e[u].b; if (v!=y) dfs(v,x); } dfn2[x]=++cnt; b[cnt]=x; } void change(int x,int k) { x=b[x]; int o; jl[x]+=k; if (jl[x]==1) o=1; else o=-1; if (ans[c[x]]>0) ans2--; ans[c[x]]+=o; if (ans[c[x]]>0) ans2++; } int lca(int x,int y) { if (dep[x]<dep[y]) swap(x,y); dep(i,20,0) if (dep[bz[i][x]]>=dep[y]) x=bz[i][x]; if (x==y) return(x); dep(i,20,0) if (bz[i][x]!=bz[i][y]) x=bz[i][x],y=bz[i][y]; return bz[0][x]; } bool cmp(re x,re y) { int k1=pos[x.a],k2=pos[y.a]; return k1<k2||(k1==k2&&x.b<y.b); } int main() { freopen("1.in","r",stdin); freopen("1.out","w",stdout); ios::sync_with_stdio(false); int T,m; cin>>T; while (T--) { me(ans); me(jl); cnt=0; ans2=0; gen(); dfs(1,0); rep(i,1,20) rep(j,1,n) bz[i][j]=bz[i-1][bz[i-1][j]]; cin>>m; rep(i,1,m) { int kk,x,y; cin>>kk>>x>>y; int k=lca(x,y); if (k!=x&&k!=y) { if (dfn1[x]>dfn1[y]) swap(x,y); a[i].a=dfn2[x],a[i].b=dfn1[y]; a[i].c=k; } else { if (y==k) swap(x,y); a[i].a=dfn1[x],a[i].b=dfn1[y]; a[i].c=0; } a[i].d=i; } int n1=2*n; block=sqrt(n1); num=(n1-1)/block+1; rep(i,1,n1) pos[i]=(i-1)/block+1; sort(a+1,a+m+1,cmp); rep(i,1,m) { if (a[i].a<=a[i-1].a) rep(j,a[i].a,a[i-1].a-1) change(j,1); if (a[i].b>=a[i-1].b) rep(j,a[i-1].b+1,a[i].b) change(j,1); if (a[i].a>a[i-1].a) rep(j,a[i-1].a,a[i].a-1) change(j,-1); if (a[i].b<a[i-1].b) rep(j,a[i].b+1,a[i-1].b) change(j,-1); if (a[i].c) { if (ans[c[a[i].c]]==0) po[a[i].d]=ans2+1; else po[a[i].d]=ans2; } else po[a[i].d]=ans2; } rep(i,1,m) wer(po[i]),wer2(); } fwrite(sr,1,CC+1,stdout); return 0; }