KunKun的征途

明天的明天,你还会送我水晶之恋吗?

导航

[POJ3468] A Simple Problem with Integers (Treap)

Posted on 2016-07-19 15:55  西域小车  阅读(161)  评论(0)    收藏  举报

题目链接:http://poj.org/problem?id=3468

这题是线段树的题,拿来学习treap。

不旋转的treap。

 

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <algorithm>
  4 #include <vector>
  5 #include <map>
  6 #include <set>
  7 #include <string>
  8 #include <bitset>
  9 #include <cmath>
 10 #include <numeric>
 11 #include <iterator>
 12 #include <iostream>
 13 #include <cstdlib>
 14 #include <functional>
 15 #include <queue>
 16 #include <stack>
 17 #include <list>
 18 #include <ctime>
 19 using namespace std;
 20 
 21 const int inf = ~0U >> 1;
 22 
 23 typedef long long LL;
 24 
 25 struct TreapNode{
 26     int id,sz,key;
 27     LL val,sum,delta;
 28     TreapNode* ch[2];
 29     TreapNode(): key(rand()),sz(1),id(0),val(0),sum(0),delta(0) {ch[0]=ch[1]=NULL;}
 30     void rz(){
 31         sz = 1;
 32         sum = val;
 33         if(ch[0]) { sz+=ch[0]->sz; sum+=ch[0]->sum; }
 34         if(ch[1]) { sz+=ch[1]->sz; sum+=ch[1]->sum; }
 35     }
 36     void pd(){
 37         if(delta){
 38             if(ch[0]) {
 39                 ch[0]->delta+=delta;
 40                 ch[0]->val+=delta;
 41                 ch[0]->sum+=delta*ch[0]->sz;
 42             }
 43             if(ch[1]) {
 44                 ch[1]->delta+=delta;
 45                 ch[1]->val+=delta;
 46                 ch[1]->sum+=delta*ch[1]->sz;
 47             }
 48             delta = 0;
 49         }
 50     }
 51     ~TreapNode(){
 52         if(ch[0]) delete ch[0];
 53         if(ch[1]) delete ch[1];
 54     }
 55 };
 56 
 57 typedef pair<TreapNode*,TreapNode*> DTreap;
 58 
 59 TreapNode* Merge(TreapNode* A,TreapNode* B) {
 60     if(!A) return B;
 61     if(!B) return A;
 62     A->pd();B->pd();
 63     if(A->key<B->key) {
 64         A->ch[1] = Merge(A->ch[1],B);
 65         A->rz();
 66         return A;
 67     } else {
 68         B->ch[0] = Merge(A,B->ch[0]);
 69         B->rz();
 70         return B;
 71     }
 72 }
 73 
 74 DTreap Split(TreapNode* rt,int id) {
 75     if(!rt) return DTreap(NULL,NULL);
 76     DTreap ret;
 77     rt->pd();
 78     if(rt->id>id) {
 79         ret = Split(rt->ch[0],id);
 80         rt->ch[0] = ret.second;
 81         ret.second = rt;
 82         rt->rz();
 83         return ret;
 84     } else {
 85         ret = Split(rt->ch[1],id);
 86         rt->ch[1] = ret.first;
 87         ret.first = rt;
 88         rt->rz();
 89         return ret;
 90     }
 91 }
 92 
 93 void Insert(TreapNode*& rt,int id,LL val) {
 94     DTreap dt = Split(rt,id-1);
 95     TreapNode* lch = dt.first;
 96     TreapNode* rch = dt.second;
 97     TreapNode* nd = new TreapNode;
 98     nd->id = id;
 99     nd->val = val;
100     nd->sum = val;
101     lch = Merge(lch,nd);
102     rt = Merge(lch,rch);
103 }
104 
105 void AddInterval(TreapNode*& rt,int l,int r,LL val) {
106     if(!rt) return;
107     DTreap dt = Split(rt,l-1);
108     TreapNode* lch = dt.first;
109     dt = Split(dt.second,r);
110     TreapNode* mid = dt.first;
111     TreapNode* rch = dt.second;
112     if(mid){
113         mid->val += val;
114         mid->sum += val*mid->sz;
115         mid->delta += val;
116     }
117     lch = Merge(lch,mid);
118     rt = Merge(lch,rch);
119 }
120 
121 LL QueryInterval(TreapNode*& rt,int l,int r) {
122     if(!rt) return 0;
123     LL ret = 0;
124     DTreap dt = Split(rt,l-1);
125     TreapNode* lch = dt.first;
126     dt = Split(dt.second,r);
127     TreapNode* mid = dt.first;
128     TreapNode* rch = dt.second;
129     if(mid) ret = mid->sum;
130     lch = Merge(lch,mid);
131     rt = Merge(lch,rch);
132     return ret;
133 }
134 
135 int n,m;
136 LL val;
137 char cmd[2];
138 
139 int main() {
140     srand(time(NULL));
141     while(~scanf("%d%d",&n,&m)) {
142         TreapNode* root = NULL;
143         for(int i = 0 ; i < n ; i++ ) {
144             scanf("%lld",&val);
145             Insert(root,i+1,val);
146         }
147         for(int i = 0 ; i < m ; i++ ) {
148             scanf("%s",cmd);
149             if(cmd[0] == 'Q' ) {
150                 int l,r;
151                 scanf("%d%d",&l,&r);
152                 printf("%lld\n",QueryInterval(root,l,r));
153             } else {
154                 int l,r;
155                 LL val;
156                 scanf("%d%d%lld",&l,&r,&val);
157                 AddInterval(root,l,r,val);
158             }
159         }
160         if(root) delete root;
161     }
162     return 0;
163 }