链接:

http://acm.hdu.edu.cn/showproblem.php?pid=1540

http://acm.hust.edu.cn/vjudge/contest/view.action?cid=82832#problem/

 

题意:

 1. D代表删除一个 X 点

 2. R代表修复最近删除的点

 3. Q查询 X 点上能连接村庄的个数

 

就说过节点上存的东西很重要,但我还是没很够很好的掌握节点上的东西,这重要的一点,以后一定要注意,如果节点上没存与答案相关的东西,我肯定写的是有问题的,这个题刚开始没怎么懂,自己写的时候在建树的时候居然只在叶子节点里面存东西,这显然是不和常理的,因次,自己写不出来也是正常,有的时候都不知道在节点里面到底要存些什么,以后要多多注意,多多思考。重要的东西强调三遍:节点里存的东西很重要! 节点里存的东西很重要! 节点里存的东西很重要!!!

 

真心不会这种区间合并更新的题, 好好学习一下, 可代码也不好看懂, 还是慢慢看吧!

 

代码:

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <cstdlib>
  5 #include <algorithm>
  6 using namespace std;
  7 
  8 #define Lson r<<1
  9 #define Rson r<<1|1
 10 #define mid a[r].Mid()
 11 
 12 const int N = 50005;
 13 
 14 struct node
 15 {
 16     int L, R;
 17     int Lsum, Rsum, sum;  // sum代表区间最大的连续区间, Lsum代表左端能到达最右端的个数
 18     int Mid() {return (R+L)>>1;}
 19     int len() {return (R-L+1);}
 20 }a[N<<2];
 21 
 22 int n, destroyed[N], k;
 23 
 24 void BuildTree(int r, int L, int R)
 25 {
 26     a[r].L=L, a[r].R=R;
 27     a[r].Lsum = a[r].Rsum = a[r].sum = a[r].len();
 28 
 29     if(L==R) return ;
 30 
 31     BuildTree(Lson, L, mid);
 32     BuildTree(Rson, mid+1, R);
 33 }
 34 
 35 void UpDate(int r)
 36 {
 37     a[r].Lsum = a[Lson].Lsum, a[r].Rsum = a[Rson].Rsum;
 38 
 39     if(a[Lson].Lsum==a[Lson].len())
 40         a[r].Lsum = a[Lson].Lsum + a[Rson].Lsum;
 41 
 42     if(a[Rson].Rsum==a[Rson].len())
 43         a[r].Rsum = a[Rson].Rsum +a[Lson].Rsum;
 44 
 45     a[r].sum = max(a[r].Lsum, max(a[r].Rsum, a[Lson].Rsum+a[Rson].Lsum));
 46 }
 47 
 48 void Insert(int r, int i, int e)
 49 {
 50     if(a[r].L==a[r].R)
 51     {
 52         a[r].Lsum = a[r].Rsum = a[r].sum = e;
 53         return ;
 54     }
 55 
 56     if(i<=mid)
 57         Insert(Lson, i, e);
 58     else if(i>mid)
 59         Insert(Rson, i, e);
 60 
 61     UpDate(r);
 62 }
 63 
 64 int Query(int r, int k)
 65 {
 66     if(a[r].sum==0) return 0;
 67     if(k<a[r].L+a[r].Lsum) return a[r].Lsum;  //判断是否在左边
 68     if(k>a[r].R-a[r].Rsum) return a[r].Rsum;  //判断是否在右边
 69     if(k>a[Lson].R-a[Lson].Rsum && k<a[Rson].L+a[Rson].Lsum)  //判断是否在中间
 70         return a[Lson].Rsum + a[Rson].Lsum;
 71 
 72     if(k<=mid)
 73         return Query(Lson, k);
 74     else
 75         return Query(Rson, k);
 76 }
 77 
 78 
 79 int main()
 80 {
 81     int  m;
 82     char s[20];
 83 
 84     while(scanf("%d%d", &n, &m)!=EOF)
 85     {
 86         int i, x;
 87 
 88         k=0;
 89         BuildTree(1, 1, n);
 90 
 91         for(i=0; i<m; i++)
 92         {
 93             scanf("%s", s);
 94             if(s[0]=='D')
 95             {
 96                 k++;
 97                 scanf("%d", &x);
 98                 destroyed[k] = x;
 99                 Insert(1, x, 0);
100             }
101             else if(s[0]=='Q')
102             {
103                 scanf("%d", &x);
104                 printf("%d\n", Query(1, x));
105             }
106             else
107             {
108                 Insert(1, destroyed[k], 1);
109                 k--;
110             }
111         }
112     }
113     return 0;
114 }

 

posted on 2015-08-01 11:24  栀蓝  阅读(218)  评论(0编辑  收藏  举报

levels of contents