zoukankan      html  css  js  c++  java
  • POJ 3321-Apple Tree-树状数组+dfs序

    计算一个树的子树节点权值和,节点权值可以单个修改。

    利用dfs序把一颗树投影到数组里,维护dfs序和子节点个数,然后用树状数组即可。

      1 #include <cstdio>
      2 #include <algorithm>
      3 #include <cstring>
      4 
      5 using namespace std;
      6 
      7 const int maxn = 1e5+10;
      8 int N,M,c[maxn],chdnum[maxn];
      9 int id_dfs[maxn],cnt_dfs;
     10 bool vis[maxn];
     11 
     12 struct Edge{
     13     int to,next;
     14 
     15 }edge[4*maxn];
     16 int head[maxn],tol;
     17 
     18 int add_edge(int u,int v)
     19 {
     20     edge[tol].to = u;
     21     edge[tol].next = head[v];
     22     head[v] = tol++;
     23 
     24     edge[tol].to = v;
     25     edge[tol].next = head[u];
     26     head[u] = tol++;
     27 }
     28 
     29 int dfs(int u)
     30 {
     31     int chd = 1;
     32     vis[u] = true;
     33     if(id_dfs[u] == -1) id_dfs[u] = cnt_dfs++;
     34 
     35     for(int i = head[u];~i;i = edge[i].next) if(!vis[edge[i].to])
     36     {
     37         int v = edge[i].to;
     38         chd += dfs(v);
     39     }
     40     return chdnum[u] = chd;
     41 }
     42 
     43 int lowbit(int x)
     44 {
     45     return x & (-x);
     46 }
     47 
     48 void update(int x,int a)
     49 {
     50     while( x <= N)
     51     {
     52         c[x] += a;
     53         x += lowbit(x);
     54     }
     55 }
     56 
     57 int getsum(int x)
     58 {
     59     int res = 0;
     60     while(x > 0)
     61     {
     62         res += c[x];
     63         x -= lowbit(x);
     64     }
     65     return res;
     66 }
     67 
     68 int query(int l,int r)
     69 {
     70     return getsum(r) - getsum(l-1);
     71 }
     72 
     73 int main()
     74 {
     75     while(~scanf("%d",&N))
     76     {
     77         memset(head,-1,sizeof head);
     78         memset(c,0,sizeof c);
     79         memset(id_dfs,-1,sizeof id_dfs);
     80         memset(vis,false,sizeof vis);
     81         cnt_dfs = 1;
     82         tol = 0;
     83 
     84         for(int i=0,u,v;i<N-1;i++)
     85         {
     86             scanf("%d%d",&u,&v);
     87             add_edge(u,v);
     88         }
     89 
     90         dfs(1);
     91 
     92         for(int i=1;i<=N;i++)
     93         {
     94             //printf("i: dfs:%d
    ",i,id_dfs[i]);
     95             update(id_dfs[i],1);
     96         }
     97         scanf("%d",&M);
     98 
     99         char op[5];
    100         int x;
    101         for(int i=0;i<M;i++)
    102         {
    103             scanf("%s%d",op,&x);
    104             //printf("sum:%d chnum:%d id:%d
    ",query(id_dfs[x],id_dfs[x]),chdnum[x],id_dfs[x]);
    105             if(op[0] == 'Q')
    106             {
    107                 printf("%d
    ",getsum(id_dfs[x]+chdnum[x]-1) - getsum(id_dfs[x]-1) );
    108             }
    109             else
    110             {
    111                 if(query(id_dfs[x],id_dfs[x])) update(id_dfs[x],-1);
    112                 else         update(id_dfs[x],1);
    113             }
    114         }
    115     }
    116 }
  • 相关阅读:
    暑假N天乐【比赛篇】 —— 2019牛客暑期多校训练营(第二场)
    莫比乌斯反演入门解析
    暑假N天乐【比赛篇】 —— 2019牛客暑期多校训练营(第一场)
    暑假N天乐 —— 多重+分组背包及变形
    暑假N天乐 —— 完全背包及变形
    暑假N天乐【比赛篇】 —— 牛客假日团队赛6
    暑假N天乐 —— 01背包及变形
    离线线段树 SPOJ
    [Python]数据类型、常量、变量和运算符(未完待续)
    [Python]从哪里开始学习写代码(未完待续)
  • 原文地址:https://www.cnblogs.com/helica/p/5281524.html
Copyright © 2011-2022 走看看