您的位置:首页 > 其它

[BZOJ3212][POJ3468]A Simple Problem with Integers

2018-03-06 20:37 253 查看

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

思路:
  Splay区间操作。

#include<cstdio>
#include<cctype>
typedef long long int64;
inline int getint() {
register char ch;
register bool neg=false;
while(!isdigit(ch=getchar())) if(ch=='-') neg=true;
register int x=ch^'0';
while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
return neg?-x:x;
}
inline char getalpha() {
register char ch;
while(!isalpha(ch=getchar()));
return ch;
}
const int N=100003;
class SplayTree {
private:
int par
,ch
[2],size
,root;
int64 val
,sum
,tag
;
void push_down(const int &p) {
if(ch

[0]) { tag[ch[p][0]]+=tag[p]; val[ch[p][0]]+=tag[p]; sum[ch[p][0]]+=tag[p]*size[ch[p][0]]; } if(ch[p][1]) { tag[ch[p][1]]+=tag[p]; val[ch[p][1]]+=tag[p]; sum[ch[p][1]]+=tag[p]*size[ch[p][1]]; } tag[p]=0; } void push_up(const int &p) { size[p]=size[ch[p][0]]+size[ch[p][1]]+1; sum[p]=sum[ch[p][0]]+sum[ch[p][1]]+val[p]; } void rotate(const int &x) { const int y=par[x],z=par[y]; push_down(y),push_down(x); const int b=x==ch[y][0]; par[ch[x][b]=par[ch[y][!b]=ch[x][b]]=y]=x; par[ch[z][ch[z][1]==y]=x]=z; push_up(y),push_up(x); } void splay(int x,const int &goal) { for(register int y=par[x],z=par[y];y!=goal;rotate(x),z=par[y=par[x]]) { if(z!=goal) rotate((x==ch[y][0])^(y==ch[z][0])?x:y); } if(!goal) root=x; } int find(int x) { for(register int y=root;;y=ch[y][size[ch[y][0]]+1<x]) { push_down(y); if(par[y]&&y==ch[par[y]][1]) x-=size[ch[par[y]][0]]+1; if(size[ch[y][0]]+1==x) return y; } } public: void build(const int &n) { for(register int i=0;i<=n+1;i++) { par[ch[i][1]=i+1]=i; if(i&&i<=n) val[i+1]=getint(); } size[n+2]=1; splay(n+2,0); } void modify(const int &l,const int &r,const int &x) { splay(find(l),0); splay(find(r+2),root); tag[ch[ch[root][1]][0]]+=x; val[ch[ch[root][1]][0]]+=x; sum[ch[ch[root][1]][0]]+=x*size[ch[ch[root][1]][0]]; } int64 query(const int &l,const int &r) { splay(find(l),0); splay(find(r+2),root); return sum[ch[ch[root][1]][0]]; } }; SplayTree t; int main() { const int n=getint(),m=getint(); t.build(n); for(register int i=0;i<m;i++) { const int opt=getalpha(),l=getint(),r=getint(); if(opt=='C') t.modify(l,r,getint()); if(opt=='Q') printf("%lld\n",t.query(l,r)); } return 0; }

[p] 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: