树分块,然后莫队,不知道为什么RE了,挖坑++
为了处理由一个转移到下一个,(莫队嘛),要做的就是把上次询问的左端点s1,和这次询问的左端点s2,求lca,然后把路径上的操作去反,右端点一样的。
为什么对,有神犇用公式证明的,然后本蒟蒻画了个草图,一看就很显然2333,但是根节点还是不显然的,,,(还是能将就着看的233)
1 #include<bits/stdc++.h> 2 #define N 1000005 3 #define LL long long 4 #define inf 0x3f3f3f3f 5 using namespace std; 6 inline int ra() 7 { 8 int x=0,f=1; char ch=getchar(); 9 while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();} 10 while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();} 11 return x*f; 12 } 13 int bin[20]; 14 int n,m,cnt,ans1; 15 int top,ind,block,blocknum,root; 16 int ans[100005],p[100005]; 17 int fa[100005][20],deep[100005]; 18 int c[100005],st[100005],dfn[100005],belong[100005]; 19 bool vis[100005]; 20 struct data{int to,next;}e[200005]; 21 int head[100005]; 22 struct query{int x,y,a,b,id;}q[200005]; 23 bool operator < (query a, query b){ 24 if (belong[a.x]==belong[b.x]) return dfn[a.y]<dfn[b.y]; 25 return belong[a.x]<belong[b.x]; 26 } 27 void insert(int x, int y) {e[++cnt].next=head[x]; e[cnt].to=y; head[x]=cnt;} 28 int dfs(int x) 29 { 30 int size=0; 31 dfn[x]=++ind; 32 for (int i=1; i<=18; i++) 33 if (deep[x]>=bin[i]) 34 fa[x][i]=fa[fa[x][i-1]][i-1]; 35 else break; 36 for (int i=head[x];i;i=e[i].next) 37 if (e[i].to!=fa[x][0]) 38 { 39 deep[e[i].to]=deep[x]+1; 40 fa[e[i].to][0]=x; 41 size+=dfs(e[i].to); 42 if (size>=block) 43 { 44 blocknum++; 45 for (int k=1; k<=size; k++) 46 belong[st[top--]]=blocknum; 47 size=0; 48 } 49 } 50 st[++top]=x; 51 return size+1; 52 } 53 int lca(int x, int y) 54 { 55 if (deep[x]<deep[y]) swap(x,y); 56 int t=deep[x]-deep[y]; 57 for (int i=0; bin[i]<=t; i++) 58 if (t&bin[i]) x=fa[x][i]; 59 for (int i=18; i>=0; i--) 60 if (fa[x][i]!=fa[y][i]) 61 x=fa[x][i],y=fa[y][i]; 62 if (x==y) return x; 63 return fa[x][0]; 64 } 65 void rever(int x) 66 { 67 if (!vis[x]) {vis[x]=1; p[c[x]]++; if (p[c[x]]==1) ans1++;} 68 else {vis[x]=0; p[c[x]]--; if (p[c[x]]==0) ans1--;} 69 } 70 void solve(int x, int y) 71 { 72 while (x!=y) 73 if (deep[x]>deep[y]) rever(x),x=fa[x][0]; 74 else rever(y),y=fa[y][0]; 75 } 76 int main() 77 { 78 bin[0]=1; for (int i=1; i<20; i++) bin[i]=bin[i-1]<<1; 79 n=ra(); m=ra(); 80 block=sqrt(n); 81 for (int i=1; i<=n; i++) c[i]=ra(); 82 for (int i=1; i<=n; i++) 83 { 84 int x=ra(),y=ra(); 85 if (!x) root=y; 86 else if (!y) root=x; 87 else insert(x,y),insert(y,x); 88 } 89 dfs(root); blocknum++; 90 while (top) belong[st[top--]]=blocknum; 91 for (int i=1; i<=m; i++) 92 { 93 q[i].x=ra(),q[i].y=ra(); 94 if (dfn[q[i].x]>dfn[q[i].y]) swap(q[i].x,q[i].y); 95 q[i].a=ra(); q[i].b=ra(); q[i].id=i; 96 } 97 sort(q+1,q+m+1); 98 int t=lca(q[1].x,q[1].y); 99 solve(q[1].x,q[1].y); rever(t); 100 ans[q[1].id]=ans1; 101 if (p[q[1].a] && p[q[1].b] && q[1].a!=q[1].b) ans[q[1].id]--; 102 rever(t); 103 for (int i=2; i<=m; i++) 104 { 105 solve(q[i-1].x,q[i].x); 106 solve(q[i-1].y,q[i].y); 107 int t=lca(q[i].x,q[i].y); 108 rever(t); 109 ans[q[i].id]=ans1; 110 if (p[q[i].a] && p[q[i].b] && q[i].a!=q[i].b) ans[q[i].id]--; 111 rever(t); 112 } 113 for (int i=1; i<=m; i++) printf("%d ",ans[i]); 114 return 0; 115 }