标签:
树上单点修改,子树查询
可以在这棵树的dfs序上建线段树维护
PS:modify、query的时候传入x的dfs序即可
1 #include<cstdio> 2 #include<cstring> 3 using namespace std; 4 const int N=100010,M=400010; 5 int size,head[N],next[N],to[N],vis[N]; 6 int st[N],ed[N],rl[M],rr[M],sum[M],cnt,n; 7 char ch[5]; 8 void uni(int x,int y){ 9 size++; 10 next[size]=head[x]; 11 head[x]=size; 12 to[size]=y; 13 } 14 void dfs(int u){ 15 st[u]=++cnt;vis[u]=1; 16 for (int e=head[u];e;e=next[e]) 17 if (!vis[to[e]]) dfs(to[e]); 18 ed[u]=cnt; 19 } 20 void update(int i){ 21 sum[i]=sum[i<<1]+sum[i<<1|1]; 22 } 23 void build(int i,int l,int r){ 24 rl[i]=l;rr[i]=r; 25 if (l==r){ 26 sum[i]=1;return; 27 } 28 int mid=(l+r)>>1; 29 build(i<<1,l,mid); 30 build(i<<1|1,mid+1,r); 31 update(i); 32 } 33 int query(int i,int L,int R){ 34 int l=rl[i],r=rr[i]; 35 if (L==l&&r==R) return sum[i]; 36 int mid=(l+r)>>1,ans=0; 37 if (L<=mid) ans=query(i<<1,L,R); 38 if (R>mid) ans+=query(i<<1|1,L,R); 39 return ans; 40 } 41 void modify(int i,int x){ 42 int l=rl[i],r=rr[i]; 43 if (l==r){ 44 sum[i]^=1;return; 45 } 46 int mid=(l+r)>>1; 47 if (x<=mid) modify(i<<1,x); 48 else modify(i<<1|1,x); 49 update(i); 50 } 51 int main(){ 52 int x,y,q; 53 scanf("%d",&n); 54 size=cnt=0; 55 for (int i=1;i<n;i++){ 56 scanf("%d %d",&x,&y); 57 uni(x,y);uni(y,x); 58 } 59 dfs(1); 60 build(1,1,n); 61 scanf("%d",&q); 62 while (q--){ 63 scanf("%s",ch); 64 scanf("%d",&x); 65 if (ch[0]==‘C‘) modify(1,st[x]); 66 else printf("%d\n",query(1,st[x],ed[x])); 67 } 68 return 0; 69 }
标签:
原文地址:http://www.cnblogs.com/Absolute-Zero/p/5930646.html