【并查集】BZOJ4551-[Tjoi2016&Heoi2016]树

NOIP太可怕了((( -口-)

题目链接

【题目大意】

给定一颗有根树(根为1),有以下两种操作:

1. 标记操作:对某个结点打上标记(在最开始,只有结点1有标记,其他结点均无标记,而且对于某个结点,可以打多次标记。)

2. 询问操作:询问某个结点最近的一个打了标记的祖先(这个结点本身也算自己的祖先)
 
【思路】
正着做不行就反方向来。先离线处理所有操作,算出最终某个点被标记了几次。跑一次dfs算出最终状态时每个点最近的打了标记的祖先u[i]。
从后往前重新看操作,如果是标记操作,那么当前节点标记数-1,如果标记数为0了,那么u[i]=fa[i]最近的祖先(用并查集来处理之前的更新)。如果为询问,则输出当前最近的祖先(同样可以用并查集来做)。
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int MAXN=100000+50;
 4 vector<int> E[MAXN];
 5 int mark[MAXN];
 6 int query[MAXN],ans[MAXN]; 
 7 int u[MAXN],fa[MAXN],n,q;
 8 char op[MAXN];
 9 
10 void dfs(int x,int anc,int father)
11 {
12     fa[x]=father;
13     if (mark[x]>0) u[x]=x;
14         else u[x]=anc;
15     for (int i=0;i<E[x].size();i++)
16     {
17         int to=E[x][i];
18         if (to==fa[x]) continue;
19         dfs(to,u[x],x);
20     }
21 }
22 
23 int union_set(int x)
24 {
25     int r=x;
26     while (u[r]!=r) r=u[r];
27     int now=x;
28     while (u[now]!=r)
29     {
30         int tmp=u[now];
31         u[now]=r;
32         now=tmp;
33     }
34     return u[x];
35 }
36 
37 void init()
38 {
39     scanf("%d%d",&n,&q);
40     for (int i=1;i<n;i++)
41     {
42         int u,v;
43         scanf("%d%d",&u,&v);
44         E[u].push_back(v);
45         E[v].push_back(u);
46     }
47     mark[1]=1;
48     for (int i=1;i<=q;i++)
49     {
50         char tmp[1];
51         scanf("%s %d",tmp,&query[i]);
52         if (tmp[0]=='C') mark[query[i]]++;
53         op[i]=tmp[0];
54     }
55     dfs(1,1,0);
56     for (int i=1;i<=n;i++) cout<<u[i]<<endl;
57 }
58 
59 void solve()
60 {
61     memset(ans,0,sizeof(ans));
62     for (int i=q;i>=1;i--)
63     {
64         int now=query[i];
65         if (op[i]=='C')
66         {
67             mark[now]--;
68             if (!mark[now]) now=union_set(fa[now]);
69         }
70         else ans[++ans[0]]=union_set(now);
71     }    
72     for (int i=ans[0];i>=1;i--) printf("%d\n",ans[i]);
73 } 
74 
75 int main()
76 {
77     init();
78     solve();
79     return 0;
80 }

 

posted @ 2016-11-19 16:25  iiyiyi  阅读(255)  评论(0编辑  收藏  举报