Codevs 1228 蘋果樹
阿新 • • 發佈:2017-08-08
ostream blog += ron 限制 war per scanf tex
輸出描述 Output Description
1228 蘋果樹
時間限制: 1 s 空間限制: 128000 KB 題目等級 : 鉆石 Diamond 題目描述 Description
在卡卡的房子外面,有一棵蘋果樹。每年的春天,樹上總會結出很多的蘋果。卡卡非常喜歡吃蘋果,所以他一直都精心的呵護這棵蘋果樹。我們知道樹是有很多分叉點的,蘋果會長在枝條的分叉點上面,且不會有兩個蘋果結在一起。卡卡很想知道一個分叉點所代表的子樹上所結的蘋果的數目,以便研究蘋果樹哪些枝條的結果能力比較強。
卡卡所知道的是,每隔一些時間,某些分叉點上會結出一些蘋果,但是卡卡所不知道的是,總會有一些調皮的小孩來樹上摘走一些蘋果。
於是我們定義兩種操作:
C x |
表示編號為x的分叉點的狀態被改變(原來有蘋果的話,就被摘掉,原來沒有的話,就結出一個蘋果) |
G x |
查詢編號為x的分叉點所代表的子樹中有多少個蘋果 |
我們假定一開始的時候,樹上全都是蘋果,也包括作為根結點的分叉1。
輸入描述 Input Description第一行一個數N (n<=100000)
接下來n-1行,每行2個數u,v,表示分叉點u和分叉點v是直接相連的。
再接下來一行一個數M,(M<=100000)表示詢問數
接下來M行,表示詢問,詢問的格式如題目所述Q x或者C x
對於每個Q x的詢問,請輸出相應的結果,每行輸出一個
樣例輸入 Sample Input3
1 2
1 3
3
Q 1
C 2
Q 1
樣例輸出 Sample Output3
2
/* 先dfs一遍,求出dfs序和每個點的子樹大小 樹就變成了一個數列,就可以用線段樹維護蘋果的數量了 list1[i]=j:節點i的dfs序為j list2[i]=j:dfs序為i的節點為j 以x為根節點的子樹的每一個節點的dfs序依次為list1[x]~list1[x]+sz[x]-1 如果x為節點的dfs序,則子樹編號dfs序依次為x~x+sz[list2[x]]-1*/ #include<iostream> #include<cstdio> using namespace std; const int maxn=100010; int sz[maxn],num,head[maxn],n,list1[maxn],p,m,opx,list2[maxn]; struct node1{ int pre,to; }e[maxn]; struct node2{ int l,r,v; }tr[maxn<<4]; void Insert(int from,int to){ e[++num].to=to; e[num].pre=head[from]; head[from]=num; } void dfs(int now){ sz[now]=1;list1[now]=++p;list2[p]=now; for(int i=head[now];i;i=e[i].pre){ dfs(e[i].to); sz[now]+=sz[e[i].to]; } } void build(int l,int r,int k){ tr[k].l=l;tr[k].r=r;tr[k].v=1; if(l==r)return; int mid=(l+r)>>1; build(l,mid,k<<1); build(mid+1,r,k<<1|1); tr[k].v=tr[k<<1].v+tr[k<<1|1].v; } char ch[5]; void change(int k){ if(tr[k].l==tr[k].r){ tr[k].v=!tr[k].v; return; } int mid=(tr[k].l+tr[k].r)>>1; if(opx<=mid)change(k<<1); else change(k<<1|1); tr[k].v=tr[k<<1].v+tr[k<<1|1].v; } int Query(int l,int r,int k){ if(tr[k].l==l&&tr[k].r==r) return tr[k].v; int mid=(tr[k].l+tr[k].r)>>1; if(r<=mid)return Query(l,r,k<<1); else if(l>mid)return Query(l,r,k<<1|1); else return Query(l,mid,k<<1)+Query(mid+1,r,k<<1|1); } int main(){ scanf("%d",&n); int x,y; for(int i=1;i<n;i++){ scanf("%d%d",&x,&y); Insert(x,y); } dfs(1); build(1,n,1); scanf("%d",&m); for(int i=1;i<=m;i++){ scanf("%s%d",ch,&opx); opx=list1[opx]; if(ch[0]==‘C‘)change(1); if(ch[0]==‘Q‘){ printf("%d\n",Query(opx,opx+sz[list2[opx]]-1,1)); } } }
Codevs 1228 蘋果樹