Splay的用法

splay区间增减查询

 1 #include<cstdio>
 2 #include<algorithm>
 3 
 4 using namespace std;
 5 
 6 const int N = 500100;
 7 const int INF = 1e9;
 8 typedef long long LL;
 9 int sum[N],data[N],siz[N],tag[N],ch[N][2],fa[N],st[N];
10 int Root,top;
11 
12 inline int read() {
13     int x = 0,f = 1;char ch = getchar();
14     for (; ch<'0'||ch>'9'; ch = getchar())
15         if (ch=='-') f = -1;
16     for (; ch>='0'&&ch<='9'; ch = getchar())
17         x = x * 10 + ch - '0';
18     return x * f;
19 }
20 inline void pushup(int x) {
21     int l = ch[x][0],r = ch[x][1];
22     siz[x] = siz[l] + siz[r] + 1;
23     sum[x] = sum[l] + sum[r] + data[x];
24 }
25 inline void pushdown(int x) {
26     if (tag[x]) {
27         int l = ch[x][0],r = ch[x][1];
28         sum[l] += siz[l] * tag[x];sum[r] += siz[r] * tag[x];
29         data[l] += tag[x];data[r] += tag[x];
30         tag[l] += tag[x];tag[r] += tag[x];
31         tag[x] = 0;
32     }
33 }
34 inline int son(int x) {
35     return x==ch[fa[x]][1];
36 }
37 inline void rotate(int x) {
38     int y = fa[x],z = fa[y],b = son(x),c = son(y),a = ch[x][!b];
39     if (z) ch[z][c] = x;else Root = x;fa[x] = z;
40     ch[x][!b] = y;fa[y] = x;
41     ch[y][b] = a;if (a) fa[a] = y;
42     pushup(y),pushup(x);
43 }
44 inline void splay(int x,int rt) {
45     top = 0;int p = x;
46     while (p) st[++top] = p,p = fa[p];
47     while (top) pushdown(st[top]),top--;
48     while (fa[x] != rt) {
49         int y =fa[x],z = fa[y];
50         if (z==rt) rotate(x);
51         else {
52             if (son(x)==son(y)) rotate(y),rotate(x);
53             else rotate(x),rotate(x);
54         }
55     }
56 }
57 inline void update(int L,int R,int a) {
58     splay(L,0);splay(R,L);
59     tag[ch[R][0]] += a;
60     sum[ch[R][0]] += siz[ch[R][0]] * a;
61     data[ch[R][0]] += a;
62     pushup(R),pushup(L);
63 }
64 inline int query(int L,int R) {
65     splay(L,0);splay(R,L);
66     return sum[ch[R][0]];
67 }
68 int build(int l,int r) {
69     if (l > r) return 0;
70     if (l==r) {
71         siz[l] = 1;sum[l] = data[l];return l;
72     }
73     int mid = (l + r) >> 1;
74     int t = build(l,mid-1);
75     fa[t] = mid;ch[mid][0] = t;
76     t = build(mid+1,r);
77     fa[t] = mid;ch[mid][1] = t;
78     pushup(mid);
79     return mid;
80 }
81 int main() {
82     int n = read(),m = read();
83     for (int i=2; i<=n+1; ++i) data[i] = read();
84     Root = build(1,n+2);
85     fa[0] = 0;
86     //char s[10];
87     for (int o,a,b,c,i=1; i<=m; ++i) {
88         o = read();
89         if (o == 1) {
90             a = read(),b = read(),c = read();
91             update(a,b+2,c);
92         }
93         else {
94             a = read(),b = read();
95             printf("%d\n",query(a,b+2));
96         }
97     }
98     return 0;
99 }
View Code

 

posted @ 2017-12-09 11:21  MJT12044  阅读(210)  评论(0编辑  收藏  举报