[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 }