• 苹果树


    题目描述 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

    题解:

      由于给定的是一棵树,要用线段树来维护的话必须是一个序列,考虑到对图或树进行深度优先搜索求出的发现时间和完成时间(时间戳)会形成一个括号化结构,这样就很好找出某个节点它的所有孩子,然后再用线段树进行单点修改,区间查询即可。

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstdlib>
      4 #include<cmath>
      5 #include<algorithm>
      6 #include<cstring>
      7 #include<vector>
      8 #include<queue>
      9 using namespace std;
     10 const int maxn=100010;
     11 inline int read(){
     12     int x=0,f=1;char ch=getchar();
     13     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     14     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
     15     return x*f;
     16 }
     17 int N,M;
     18 int tot=1;
     19 vector<int> to[maxn];
     20 int a[maxn*8],b[maxn*8];
     21 int fa[maxn*8];
     22 char s[10];
     23 struct POS{
     24     int l,r;
     25     int cnt;
     26 }pos[maxn*8];
     27 inline void dfs(int rt){
     28     for(int i=0;i<to[rt].size();i++){
     29         int y=to[rt][i];
     30         if(y!=fa[rt]){
     31             a[++tot]=y; fa[y]=rt;    
     32             dfs(y);
     33         }
     34     }
     35     if(to[rt].size()>1) a[++tot]=rt;
     36 }
     37 struct node{
     38     int l,r;
     39     int sum;
     40 }seg[maxn*8];
     41 inline void build(int rt,int l,int r){
     42     seg[rt].l=l; seg[rt].r=r;
     43     if(l==r){
     44         seg[rt].sum=b[l]; return ;
     45     }
     46     int mid=(l+r)>>1;
     47     build(rt*2,l,mid); build(rt*2+1,mid+1,r);
     48     seg[rt].sum=seg[rt*2].sum+seg[rt*2+1].sum;
     49 }
     50 inline void change(int rt,int tar){
     51     if(seg[rt].l==seg[rt].r){
     52         if(seg[rt].sum==1) seg[rt].sum=0;
     53         else seg[rt].sum=1;
     54         return ;
     55     }
     56     int mid=(seg[rt].l+seg[rt].r)>>1;
     57     if(tar<=mid) change(rt*2,tar);
     58     else change(rt*2+1,tar);
     59     seg[rt].sum=seg[rt*2].sum+seg[rt*2+1].sum;
     60 }
     61 inline int query(int rt,int l,int r){
     62     if(l<=seg[rt].l&&seg[rt].r<=r){
     63         return seg[rt].sum;
     64     }
     65     int mid=(seg[rt].l+seg[rt].r)>>1;
     66     int ans=0;
     67     if(l<=mid) ans+=query(rt*2,l,r);
     68     if(mid+1<=r) ans+=query(rt*2+1,l,r);
     69     return ans; 
     70 }
     71 int main(){
     72    // freopen("apple.in","r",stdin);
     73    // freopen("apple.out","w",stdout);
     74     N=read();
     75     for(int i=1;i<=N-1;i++){
     76         int u=read(),v=read();
     77         to[u].push_back(v); to[v].push_back(u);
     78     }
     79     fa[1]=-1; a[tot]=1; dfs(1);
     80     for(int i=1;i<=tot;i++){
     81         int temp=++pos[a[i]].cnt;
     82         if(temp==1) pos[a[i]].l=i;
     83         else pos[a[i]].r=i;
     84     }
     85     for(int i=1;i<=N;i++) b[pos[i].l]=1;
     86     build(1,1,tot);
     87     M=read();
     88     for(int i=1,tmp;i<=M;i++){
     89         scanf("%s",s);
     90         if(s[0]=='Q'){
     91             tmp=read();
     92             if(pos[tmp].cnt==1) cout<<query(1,pos[tmp].l,pos[tmp].l)<<endl;
     93             else cout<<query(1,pos[tmp].l,pos[tmp].r)<<endl;
     94         }
     95         else{
     96             tmp=read();
     97             change(1,pos[tmp].l);
     98         }
     99     }
    100     return 0;
    101 }
  • 相关阅读:
    六种常见排序算法的自我研究(冒泡排序,选择排序,快速排序,归并排序,插入排序,堆排序)
    设计模式学习总结(二)工厂模式
    SQL Server Reporting Service(SSRS) 第七篇 常见错误汇总
    SQL Server Reporting Service(SSRS) 第六篇 SSRS 部署总结
    设计模式学习总结(一)简单工厂模式
    设计模式学习总结(三)抽象工厂模式
    设计模式学习总结(四)单例模式
    SQL Server覆盖索引--有无包含列对数据库查询性能的影响分析
    Dev Express Report 学习总结(八)Dev Express Reports 常见问题总结
    docker命令笔记
  • 原文地址:https://www.cnblogs.com/CXCXCXC/p/5004659.html
Copyright © 2020-2023  润新知