【POJ2761】【fhq treap】A Simple Problem with Integers

Description

You have N integers, A1A2, ... , AN. You need to deal with two kinds of operations. One type of operation is to add some given number to each number in a given interval. The other is to ask for the sum of numbers in a given interval.

Input

The first line contains two numbers N and Q. 1 ≤ N,Q ≤ 100000.
The second line contains N numbers, the initial values of A1A2, ... , AN. -1000000000 ≤ Ai ≤ 1000000000.
Each of the next Q lines represents an operation.
"C a b c" means adding c to each of AaAa+1, ... , Ab. -10000 ≤ c ≤ 10000.
"Q a b" means querying the sum of AaAa+1, ... , Ab.

Output

You need to answer all Q commands in order. One answer in a line.

Sample Input

10 5

1 2 3 4 5 6 7 8 9 10

Q 4 4

Q 1 10

Q 2 4

C 3 6 3

Q 2 4

Sample Output

4

55

9

15

Hint

The sums may exceed the range of 32-bit integers.

Source

【分析】
这个其实是个水题。我只是拿来fhq treap的...
Orzzzzzz范大爷
这种数据结构真是...能保证treap的性质同时也能保证合并后的树还能原封不动的切出来...
说它是treap,我觉得就一个fix像treap而已。
这个数据结构的精髓在合并和分裂(和打标记?)。有注释.
  1 #include <iostream>

  2 #include <cstdio>

  3 #include <algorithm>

  4 #include <cstring>

  5 #include <vector>

  6 #include <utility>

  7 #include <iomanip>

  8 #include <string>

  9 #include <cmath>

 10 #include <queue>

 11 #include <assert.h>

 12 #include <map>

 13 #include <ctime>

 14 #include <cstdlib>

 15 #define LOCAL

 16 const int MAXN = 100000 + 10;

 17 const int INF = 0x3f3f3f3f;

 18 const int SIZE = 450;

 19 const int maxnode =  1101000;

 20 using namespace std;

 21 typedef long long ll;

 22 ll n, m;

 23 struct fhqTreap{

 24        struct Node{

 25               Node *l, *r;

 26               ll delta, sum;

 27               ll size, fix, val;

 28        }*root, *null, mem[1101000];

 29        ll tot;

 30        

 31        ll BIG_RAND(){return (ll)rand()*RAND_MAX + (ll)rand();}

 32        void init(){

 33             tot = 0;

 34             NEW(null, 0);

 35             null->size = 0;

 36             root = null;

 37             insert(0, n);//插入 

 38        }

 39        void update(Node *t){

 40             if (t == null) return;

 41             t->size = t->l->size + t->r->size + 1;

 42             t->sum = t->val;

 43             if (t->l != null) t->sum += t->l->sum;

 44             if (t->r != null) t->sum += t->r->sum; 

 45        }

 46        //标记下传=-= 

 47        void push_down(Node *t){

 48             if (t->delta){

 49                t->val += t->delta;

 50                

 51                if (t->l != null) {t->l->delta += t->delta, t->l->sum += t->l->size * t->delta;}

 52                if (t->r != null) {t->r->delta += t->delta, t->r->sum += t->r->size * t->delta;}

 53                

 54                t->delta = 0;

 55             }

 56        }

 57        

 58        void NEW(Node *&t, ll val){

 59             t = &mem[tot++];

 60             t->size = 1;

 61             t->fix = BIG_RAND();

 62             t->sum = t->val = val;

 63             t->delta = 0;

 64             t->l = t->r = null; 

 65        }

 66        //将t分裂为大小p和t->size - p的两个子树  

 67        void split(Node *t, Node *&a, Node *&b, int p){

 68             if (t->size <= p) a = t, b = null;

 69             else if (p == 0) a = null, b = t;

 70             else {

 71                  push_down(t);

 72                  if (t->l->size >= p){

 73                     b = t;

 74                     split(t->l, a , b->l, p);

 75                     update(b);

 76                  }else{

 77                     a = t;

 78                     split(t->r, a->r, b, p - t->l->size - 1);

 79                     update(a); 

 80                  }

 81             }

 82        }

 83        //将a,b树合并为t 

 84        void merge(Node *&t, Node *a, Node *b){

 85             if (a == null) t = b;

 86             else if (b == null) t = a;

 87             else {

 88                  if (a->fix > b->fix){//按fix值排序

 89                     push_down(a);

 90                     t = a;

 91                     merge(t->r, a->r, b);

 92                  }else{

 93                     push_down(b);

 94                     t = b;

 95                     merge(t->l, a, b->l); 

 96                  }

 97                  update(t);

 98             }

 99        }

100        void add(ll l, ll r, ll val){

101             Node *a, *b, *c;

102             split(root, a, b, l - 1);

103             split(b, b, c, r - l + 1);

104             b->delta += val;

105             b->sum += val * b->size;

106             merge(a, a, b);

107             merge(root, a, c);

108        }

109        ll query(ll l, ll r){

110           Node *a, *b, *c;

111           split(root, a, b, l - 1);

112           split(b, b, c, r - l + 1);

113           ll ans = b->sum;

114           merge(b, b, c);

115           merge(root, a, b);

116           return ans;

117        }

118        //把b挤出去 

119        void Delete(ll p){

120             Node *a, *b, *c;

121             split(root, a, b, p - 1);

122             split(b, b, c, 1);

123             merge(root, a, c);

124        }

125        Node *Insert(ll x){//不可思议的插入方式 

126             if (x == 0) return null;

127             if (x == 1){

128                ll tmp;

129                scanf("%lld", &tmp);

130                Node *a;

131                NEW(a, tmp);

132                return a;

133             } 

134             Node *a, *b;

135             int mid = x / 2;

136             a = Insert(mid);

137             b = Insert(x - mid);

138             merge(a, a, b);

139             return a;

140        } 

141 

142        //在pos处插入x个数字 

143        void insert(ll pos, ll x){

144             Node *a, *b, *c, *t;

145             //跟块状链表的有点像,分裂再合并 

146             split(root, a, b, pos);

147             c = Insert(x);//插入一个值为x的树 

148             merge(a, a, c);

149             merge(root, a, b);

150        }

151 }A;

152 

153 void work(){

154      char str[3];

155      while (m--){

156            scanf("%s", str);

157            if (str[0] == 'Q'){

158               ll l, r;

159               scanf("%lld%lld", &l, &r);

160               printf("%lld\n", A.query(l, r));

161            }else{

162               ll l, r, k;

163               scanf("%lld%lld%lld", &l, &r, &k);

164               A.add(l, r, k);

165            }

166      }

167 }

168 

169 int main(){

170     

171     while( scanf("%lld%lld", &n, &m) != EOF){

172            A.init();

173            work();

174     }

175     return 0;

176 }
View Code

 

你可能感兴趣的:(Integer)