线段树

 

线段树:http://blog.csdn.net/shiqi_614/article/details/8228102(帖子总结的很好,可以参考题目)

http://blog.csdn.net/metalseed/article/details/8039326

特性:平衡二叉树,查询和插入都是log(n)

线段树:

1)单点更新

2)区间更新,用延迟标记,避免区间左右儿子进行更新操作;只有当query时才需要进行更新;

3)区间合并 

线段树的类:实现区间增加一个值,并延迟更新

  1. #define LL(x) (x<<1)  
  2. #define RR(x) (x<<1|1)  
  3. #define MID(a,b) (a+((b-a)>>1))  
  4. const int N=100005;  
  5. typedef long long LL;  
  6. struct node  
  7. {  
  8. int lft,rht;  
  9.     LL sum,add;  
  10. int mid(){return MID(lft,rht);}  
  11. void fun(LL tmp)  
  12.     {  
  13.         add+=tmp;  
  14.         sum+=(rht-lft+1)*tmp;  
  15.     }  
  16. };  
  17. int y[N];  
  18. struct Segtree  
  19. {  
  20.     node tree[N*4];  
  21. void relax(int ind)  
  22.     {  
  23. if(tree[ind].add)  
  24.         {  
  25.             tree[LL(ind)].fun(tree[ind].add);  
  26.             tree[RR(ind)].fun(tree[ind].add);  
  27.             tree[ind].add=0;  
  28.         }  
  29.     }  
  30. void build(int lft,int rht,int ind)  
  31.     {  
  32.         tree[ind].lft=lft;  tree[ind].rht=rht;  
  33.         tree[ind].sum=0;    tree[ind].add=0;  
  34. if(lft==rht) tree[ind].sum=y[lft];  
  35. else   
  36.         {  
  37. int mid=tree[ind].mid();  
  38.             build(lft,mid,LL(ind));  
  39.             build(mid+1,rht,RR(ind));  
  40.             tree[ind].sum=tree[LL(ind)].sum+tree[RR(ind)].sum;  
  41.         }  
  42.     }  
  43. void updata(int st,int ed,int ind,int add)  
  44.     {  
  45. int lft=tree[ind].lft,rht=tree[ind].rht;  
  46. if(st<=lft&&rht<=ed) tree[ind].fun(add);  
  47. else   
  48.         {  
  49.             relax(ind);  
  50. int mid=tree[ind].mid();  
  51. if(st<=mid) updata(st,ed,LL(ind),add);  
  52. if(ed> mid) updata(st,ed,RR(ind),add);  
  53.             tree[ind].sum=tree[LL(ind)].sum+tree[RR(ind)].sum;  
  54.         }  
  55.     }  
  56.     LL query(int st,int ed,int ind)  
  57.     {  
  58. int lft=tree[ind].lft,rht=tree[ind].rht;  
  59. if(st<=lft&&rht<=ed) return tree[ind].sum;  
  60. else  
  61.         {  
  62.             relax(ind);  
  63. int mid=tree[ind].mid();  
  64.             LL sum1=0,sum2=0;  
  65. if(st<=mid) sum1=query(st,ed,LL(ind));  
  66. if(ed> mid) sum2=query(st,ed,RR(ind));  
  67. return sum1+sum2;  
  68.         }  
  69.     }  
  70. }seg;  

基本实现:主要实现单点更新

  1. #include<iostream>
  2. using namespace std;
  3. struct TreeNode{
  4.   int start;
  5.   int end;
  6.   int cnt;
  7.   TreeNode *left;
  8.   TreeNode *right;
  9.   TreeNode(int start,int end):start(start),end(end){
  10.     left = NULL;
  11.     right = NULL;
  12.     cnt=0;
  13.   }
  14. };
  15. void update(TreeNode *root, int i,int cnt,bool flag) {
  16.     if(root==NULL) return;
  17.     if(root->start <= i && i<=root->end) {
  18.         if(flag == true) root->cnt += cnt;
  19.         else root->cnt -= cnt;
  20.         int mid = root->start + (root->end - root->start)/2;
  21.         if(i>mid) update(root->right,i,cnt,flag);
  22.         else update(root->left,i,cnt,flag);
  23.     }
  24. }
  25. int query(TreeNode *root,int i,int j) {
  26.     if(root==NULL) return 0;
  27.     if(i>j) return 0;
  28.     int start = root->start;
  29.     int end = root->end;
  30.     int mid = start + (end-start)/2;
  31.     if(start==i && j==end) return root->cnt;
  32.     if(j<=mid) return query(root->left,i,j);
  33.     else if(i<=mid) return query(root->left,i,mid) + query(root->right,mid+1,j); 
  34.     else return query(root->right,i,j);
  35. }
  36. TreeNode *  addSegTree(int start,int end) {
  37.         TreeNode * root = new TreeNode(start,end);
  38.         if(start!=end) {
  39.             int mid = start + (end-start)/2;
  40.             root->left  = addSegTree(start,mid);
  41.             root->right = addSegTree(mid+1,end);
  42.         }
  43.         return root;
  44. }
  45. void preorder(TreeNode *root) {
  46.     if(root==NULL) return;
  47.     cout<<"["<<root->start<<","<<root->end<<"]"<<endl;
  48.     preorder(root->left);
  49.     preorder(root->right);
  50. }
  51. int main(){
  52.     int start=1;
  53.     int end=10;
  54.     // cin>>start>>end;
  55.      TreeNode *root = addSegTree(start,end);
  56.      for(int i=1;i<=10;i++)
  57.          update(root,i,i,true);
  58.      cout<<query(root,1,3)<<endl;
  59.      update(root,3,6,true);
  60.      cout<<query(root,2,7)<<endl;
  61.      update(root,10,2,false);
  62.      update(root,6,3,true);
  63.      cout<<query(root,3,10)<<endl;
  64.     // preorder(root);
  65.      return 0;
  66. }
posted @ 2014-07-21 16:25  purejade  阅读(115)  评论(0编辑  收藏  举报