标签:color 离线处理 exp i++ 树链剖分 put data scan 输出
这道题是可以用树链剖分来做的,但其实有比它更加简单的做法——并查集。
可以想到,这类题的一种常见做法是离线处理,先全部读入,再从后往前处理,每次遇到标记操作,就把这个点的标记次数减一,到零以后就把这个点的前继连到它的父亲上。
然后再倒序输出答案即可。
Code:
1 #include<cstdio> 2 #include<vector> 3 using namespace std; 4 const int maxn=100010; 5 struct data{ 6 char str[2]; 7 int dot; 8 }query[maxn]; 9 int ans[maxn]; 10 int n,q,mark[maxn],fa[maxn],par[maxn],t=0; 11 vector <int> a[maxn]; 12 void readin(){ 13 scanf("%d%d",&n,&q); 14 mark[1]=1; 15 for (int i=1; i<n; i++){ 16 int u,v; 17 scanf("%d%d",&u,&v); 18 a[u].push_back(v); 19 a[v].push_back(u); 20 } 21 for (int i=1; i<=q; i++){ 22 scanf("%s%d",query[i].str,&query[i].dot); 23 if (query[i].str[0]==‘C‘) mark[query[i].dot]++; 24 } 25 } 26 int find(int x){ 27 if (par[x]==x) return x; 28 else return par[x]=find(par[x]); 29 } 30 void dfs(int s,int p){ 31 if (mark[s]) par[s]=s; 32 else par[s]=find(p); 33 for (int i=0; i<a[s].size(); i++){ 34 int now=a[s][i]; 35 if (now==p) continue; 36 fa[now]=s; 37 dfs(now,s); 38 } 39 } 40 void solve(){ 41 dfs(1,0); 42 for (int i=q; i>0; i--){ 43 if (query[i].str[0]==‘Q‘){ 44 ans[++t]=find(query[i].dot); 45 } 46 else { 47 int now=query[i].dot; 48 mark[now]--; 49 if (mark[now]==0) par[now]=find(fa[now]); 50 } 51 } 52 } 53 void putout(){ 54 for (int i=t; i>=1; i--) printf("%d\n",ans[i]); 55 } 56 int main(){ 57 readin(); 58 solve(); 59 putout(); 60 return 0; 61 }
标签:color 离线处理 exp i++ 树链剖分 put data scan 输出
原文地址:http://www.cnblogs.com/Robinson828/p/6091389.html