codevs——1228 蘋果樹

來源:互聯網
上載者:User

標籤:std   algo   表示   cin   void   href   space   forward   ref   

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

 

拿到這個題目以後,我們第一眼看到的會是:有m次詢問,每次詢問2種操作。那麼就可以很快的get到這個題是要用線段樹。

但是問題又來了,現在他給我們的是一個樹啊,而且我們線段樹維護的是一個序列,那我們就要先辦法將這棵樹轉化成一個序列

我們想一下要用什麼方法完成這個操作呢??  對!就是dfs序!

我們現對於我們建出來的樹跑一遍dfs,然後求出每一個節點的dfs序,同時處理出每一個節點的子樹的大小,這樣我們可以保證每一棵子樹內的所有的節點都是相連的。以一個節點為子樹的區間即為從這個節點到這個節點+其子樹的大小+1,當我們詢問一個節點的蘋果個數是既可以轉換成詢問這個區間的大小。在我們進行蘋果的更改時,即為對一個點進行單點修改,我們進行單點修改的時候我們直接對其進行取反既可以。

#include<cstdio>#include<cstdlib>#include<cstring>#include<iostream>#include<algorithm>#define N 110000using namespace std;char ch;int n,m,q,x,y,s,tot,ans;int head[N],size[N],list1[N],list2[N];int read(){    int x=0,f=1; char ch=getchar();    while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1; ch=getchar();}    while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘; ch=getchar();}    return x*f;}struct Edge{    int next,to,from;}edge[N<<1];int add(int x,int y){    tot++;    edge[tot].to=y;    edge[tot].next=head[x];    head[x]=tot;}struct Tree{    int l,r,w;}tree[N*4];int dfs(int x){    size[x]=1,list1[x]=++s,list2[s]=x;    for(int i=head[x];i;i=edge[i].next)    {        int t=edge[i].to;        dfs(t);        size[x]+=size[t];    }}void build(int k,int l,int r){    tree[k].l=l,tree[k].r=r;    if(tree[k].l==tree[k].r)    {        tree[k].w=1;        return ;    }    int mid=(tree[k].l+tree[k].r)>>1;    build(k<<1,l,mid);    build(k<<1|1,mid+1,r);    tree[k].w=tree[k<<1].w+tree[k<<1|1].w;}void change_point(int k){    if(tree[k].l==tree[k].r)    {        tree[k].w=!tree[k].w;        return ;    }    int mid=(tree[k].r+tree[k].l)/2;    if(x<=mid) change_point(k<<1);    else change_point(k<<1|1);    tree[k].w=tree[k<<1].w+tree[k<<1|1].w;}void ask_interval(int k){    if(tree[k].l>=x&&tree[k].r<=y)    {        ans+=tree[k].w;        return ;    }    int mid=(tree[k].l+tree[k].r)>>1;    if(x<=mid) ask_interval(k<<1);    if(y>mid)  ask_interval(k<<1|1);}int main(){    n=read();    for(int i=1;i<n;i++)     x=read(),y=read(),add(x,y);    dfs(1);    build(1,1,n);    m=read();    while(m--)    {        cin>>ch;        q=read();        x=list1[q];ans=0;        if(ch==‘C‘) change_point(1);        else         {            y=x+size[q]-1;ask_interval(1);            printf("%d\n",ans);        }    }    return 0;}

 

codevs——1228 蘋果樹

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.