链接:
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 ", Query(1, x)); 105 } 106 else 107 { 108 Insert(1, destroyed[k], 1); 109 k--; 110 } 111 } 112 } 113 return 0; 114 }