1. 程式人生 > >Codevs 1228 蘋果樹

Codevs 1228 蘋果樹

ostream blog += ron 限制 war per scanf tex

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

輸出描述 Output Description

對於每個Q x的詢問,請輸出相應的結果,每行輸出一個

樣例輸入 Sample Input

3

1 2

1 3

3

Q 1

C 2

Q 1

樣例輸出 Sample Output

3

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 蘋果樹