nodeoj2000——Freda's Chess

DFS序加线段树,很模板


 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <cmath>
 5 #include <algorithm>
 6 using namespace std;
 7 const int maxn=200005;
 8 int n,m,y,x,idx,cnt,in[maxn],head[maxn],out[maxn];
 9 int ct,root=1;
10 char ju;
11 struct edge{
12     int v,nxt;
13 }d[maxn];
14 inline void add(int a,int b){
15     d[++cnt].v=b;d[cnt].nxt=head[a];head[a]=cnt;
16     d[++cnt].v=a;d[cnt].nxt=head[b];head[b]=cnt;
17 }
18 struct TREE{
19     int l,r,sum;
20 }t[maxn<<2];
21 void dfs(int u,int fa){
22     in[u]=++idx;
23     for(int i=head[u];i;i=d[i].nxt){
24         int v=d[i].v;
25         if(v==fa)continue;
26         dfs(v,u);
27     }
28     out[u]=idx;
29 }
30 void build(int ro,int l,int r){
31     t[ro].l=l,t[ro].r=r;
32     if(l==r){
33         t[ro].sum=1;
34         return;
35     }
36     int mid=l+r>>1;
37     build(ro<<1,l,mid);
38     build(ro<<1|1,mid+1,r);
39     t[ro].sum=t[ro<<1].sum+t[ro<<1|1].sum;
40 }
41 void update(int ro,int pos){
42     if(t[ro].l==pos&&t[ro].r==pos){
43         t[ro].sum^=1;
44         return;
45     }
46     int mid=t[ro].l+t[ro].r>>1;
47     if(pos<=mid)update(ro<<1,pos);
48     else update(ro<<1|1,pos);
49     t[ro].sum=t[ro<<1].sum+t[ro<<1|1].sum;
50 }
51 int query(int ro,int l,int r){
52     if(t[ro].l==l&&t[ro].r==r){
53         return t[ro].sum;
54     }
55     int mid=t[ro].l+t[ro].r>>1;
56     if(r<=mid)return query(ro<<1,l,r);
57     else if(l>mid)return query(ro<<1|1,l,r);
58     else return query(ro<<1,l,mid)+query(ro<<1|1,mid+1,r);
59 }
60 
61 
62 int main(){
63     ios::sync_with_stdio(false);
64     cin>>n;
65     for(int i=1;i<n;++i){
66         cin>>x>>y;
67         add(x,y);
68     }
69     dfs(1,0);
70     build(root,1,idx);
71     cin>>m;
72     while(m--){
73         cin>>ju>>x;
74         if(ju=='C')update(root,in[x]);
75         else printf("%d\n",query(root,in[x],out[x]));
76     }
77     return 0;
78 }

 

转载于:https://www.cnblogs.com/AT-HENS/p/7756869.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值