zoukankan      html  css  js  c++  java
  • POJ 3321 Apple Tree dfs+二叉索引树

    题目:http://poj.org/problem?id=3321

    动态更新某个元素,并且求和,显然是二叉索引树,但是节点的标号不连续,二叉索引树必须是连续的,所以需要转化成连续的,多叉树的形状已经建好,只要重新标号成连续的就行了。

    感觉重新标号是这个题最难的地方,否则就是个纯水题了。。。

    重新标号是看的别人的。。。用dfs遍历多叉树标号。

      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #include <string.h>
      4 
      5 int item = 0;
      6 int c[100010], n;
      7 int start[100010], end[100010];
      8 
      9 struct Tree
     10 {
     11     int num;
     12     struct Tree *next;
     13     Tree()
     14     {
     15         next = NULL;
     16         num = 0;
     17     }
     18 }tree[100010];
     19 
     20 int lowbit(int x)
     21 {
     22     return x & (-x);
     23 }
     24 
     25 void add(int x, int y)
     26 {
     27     while(x <= n)
     28     {
     29         c[x] += y;
     30         x += lowbit(x);
     31     }
     32 }
     33 
     34 int sum(int x)
     35 {
     36     int ret = 0;
     37     while(x)
     38     {
     39         ret += c[x];
     40         x -= lowbit(x);
     41     }
     42     return ret;
     43 }
     44 
     45 int query(int x, int y)
     46 {
     47     return sum(y) - sum(x-1);
     48 }
     49 
     50 void dfs(int x)
     51 {
     52     start[x] = ++item;
     53     struct Tree *p = tree[x].next;
     54     while(p != NULL)
     55     {
     56         if(start[p->num] == 0)
     57             dfs(p->num);
     58         p = p->next;
     59     }
     60     end[x] = item;
     61 }
     62 
     63 int main()
     64 {
     65     int u, v;
     66     scanf("%d", &n);
     67     memset(tree, 0, sizeof(tree));
     68     memset(start, 0, sizeof(start));
     69     memset(c, 0, sizeof(c));
     70     for(int i = 1; i < n; i++)
     71     {
     72         scanf("%d %d", &u, &v);
     73         struct Tree *p = new Tree;
     74         p->num = v;
     75         p->next = tree[u].next;
     76         tree[u].next = p;
     77     }
     78     dfs(1);
     79     for(int i = 1; i <= n; i++)
     80     {
     81         add(i, 1);
     82     }
     83     int q, z;
     84     char cmd[2];
     85     scanf("%d", &q);
     86     while(q--)
     87     {
     88         scanf("%s %d", cmd, &z);
     89         if(cmd[0] == 'Q')
     90         {
     91             printf("%d
    ", query(start[z], end[z]));
     92         }
     93         else
     94         {
     95             if(sum(start[z]) - sum(start[z]-1) == 1)
     96                 add(start[z], -1);
     97             else add(start[z], 1);
     98         }
     99     }
    100     return 0;
    101 }
    View Code
  • 相关阅读:
    Nginx支持WebSocket反向代理-学习小结
    CentOS6.9下升级默认的OpenSSH操作记录(升级到OpenSSH_7.6p1)
    CentOS 6下gcc升级的操作记录(由默认的4.4.7升级到6.4.0版本)
    Docker容器内部端口映射到外部宿主机端口
    Linux下分布式系统以及CAP理论分析
    C/ C++ 快速上手
    YUV视频格式详解(翻译自微软文档)
    YUV详解
    阿里云ECS使用vnc远程连接(Ubuntu + CentOS)
    oh-my-zsh: 让终端飞
  • 原文地址:https://www.cnblogs.com/wolfred7464/p/3320056.html
Copyright © 2011-2022 走看看