[BZOJ3212][POJ3468]A Simple Problem with Integers

题目大意:
  维护一个长度为$n(n\leq100000)$的数列,支持区间加、区间求和两种操作,操作共$m(m\leq100000)$次。

思路:
  Splay区间操作。

 1 #include<cstdio>
 2 #include<cctype>
 3 typedef long long int64;
 4 inline int getint() {
 5     register char ch;
 6     register bool neg=false;
 7     while(!isdigit(ch=getchar())) if(ch=='-') neg=true;
 8     register int x=ch^'0';
 9     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
10     return neg?-x:x;
11 }
12 inline char getalpha() {
13     register char ch;
14     while(!isalpha(ch=getchar()));
15     return ch;
16 }
17 const int N=100003;
18 class SplayTree {
19     private:
20         int par[N],ch[N][2],size[N],root;
21         int64 val[N],sum[N],tag[N];
22         void push_down(const int &p) {
23             if(ch[p][0]) {
24                 tag[ch[p][0]]+=tag[p];
25                 val[ch[p][0]]+=tag[p];
26                 sum[ch[p][0]]+=tag[p]*size[ch[p][0]];
27             }
28             if(ch[p][1]) {
29                 tag[ch[p][1]]+=tag[p];
30                 val[ch[p][1]]+=tag[p];
31                 sum[ch[p][1]]+=tag[p]*size[ch[p][1]];
32             }
33             tag[p]=0;
34         }
35         void push_up(const int &p) {
36             size[p]=size[ch[p][0]]+size[ch[p][1]]+1;
37             sum[p]=sum[ch[p][0]]+sum[ch[p][1]]+val[p];
38         }
39         void rotate(const int &x) {
40             const int y=par[x],z=par[y];
41             push_down(y),push_down(x);
42             const int b=x==ch[y][0];
43             par[ch[x][b]=par[ch[y][!b]=ch[x][b]]=y]=x;
44             par[ch[z][ch[z][1]==y]=x]=z;
45             push_up(y),push_up(x);
46         }
47         void splay(int x,const int &goal) {
48             for(register int y=par[x],z=par[y];y!=goal;rotate(x),z=par[y=par[x]]) {
49                 if(z!=goal) rotate((x==ch[y][0])^(y==ch[z][0])?x:y);
50             }
51             if(!goal) root=x;
52         }
53         int find(int x) {
54             for(register int y=root;;y=ch[y][size[ch[y][0]]+1<x]) {
55                 push_down(y);
56                 if(par[y]&&y==ch[par[y]][1]) x-=size[ch[par[y]][0]]+1;
57                 if(size[ch[y][0]]+1==x) return y;
58             }
59         }
60     public:
61         void build(const int &n) {
62             for(register int i=0;i<=n+1;i++) {
63                 par[ch[i][1]=i+1]=i;
64                 if(i&&i<=n) val[i+1]=getint();
65             }
66             size[n+2]=1;
67             splay(n+2,0);
68         }
69         void modify(const int &l,const int &r,const int &x) {
70             splay(find(l),0);
71             splay(find(r+2),root);
72             tag[ch[ch[root][1]][0]]+=x;
73             val[ch[ch[root][1]][0]]+=x;
74             sum[ch[ch[root][1]][0]]+=x*size[ch[ch[root][1]][0]];
75         }
76         int64 query(const int &l,const int &r) {
77             splay(find(l),0);
78             splay(find(r+2),root);
79             return sum[ch[ch[root][1]][0]];
80         }
81 };
82 SplayTree t;
83 int main() {
84     const int n=getint(),m=getint();
85     t.build(n);
86     for(register int i=0;i<m;i++) {
87         const int opt=getalpha(),l=getint(),r=getint();
88         if(opt=='C') t.modify(l,r,getint());
89         if(opt=='Q') printf("%lld\n",t.query(l,r));
90     }
91     return 0;
92 }

 

posted @ 2018-03-06 20:37  skylee03  阅读(135)  评论(0编辑  收藏  举报