题解:
。。感觉挺烦得 而且我都没有注意到树随机这件事情。。
就写个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; }