标签:splay
题意:有两种操作: 1. C l r x: 区间[l,r]的数加x。 2. Q l r : 查询区间[l,r]的和。
思路:线段树的裸题,只是为了练习splay。详见代码:
/********************************************************* file name: poj3468.cpp author : kereo create time: 2015年01月28日 星期三 15时03分07秒 *********************************************************/ #include<iostream> #include<cstdio> #include<cstring> #include<queue> #include<set> #include<map> #include<vector> #include<stack> #include<cmath> #include<string> #include<algorithm> using namespace std; typedef long long ll; const int sigma_size=26; const int N=100+50; const int MAXN=100000+50; const int inf=0x3fffffff; const double eps=1e-8; const int mod=100000000+7; #define L(x) (x->ch[0]) #define R(x) (x->ch[1]) #define PII pair<int, int> #define mk(x,y) make_pair((x),(y)) int n,m,cnt,top; int st[MAXN]; char str[N]; ll num[MAXN]; struct node{ int sz; ll val,sum,tag; node *fa,*ch[2]; }nod[MAXN],nil,*root,*null; struct Splay{ void rotate(node *x,int d){ node *y=x->fa; push_down(y); push_down(x); y->ch[d^1]=x->ch[d]; if(x->ch[d]!=null) x->ch[d]->fa=y; x->fa=y->fa; if(y->fa!=null){ int d1=y->fa->ch[0] == y ? 0 : 1; y->fa->ch[d1]=x; } y->fa=x; x->ch[d]=y; push_up(y); } void splay(node *x,node *fa){ while(x->fa!=fa){ push_down(x); node *y=x->fa; if(y->fa == fa){ int d=y->ch[0] == x ? 1 : 0; rotate(x,d); } else{ int d=y->fa->ch[0] == y ? 1 : 0; if(y->ch[d] == x){ rotate(x,d^1); rotate(x,d); } else{ rotate(y,d); rotate(x,d); } } } push_up(x); if(fa == null) root=x; } void rotateto(int k,node *fa){ node *rt=root; push_down(rt); while(L(rt)->sz!=k){ if(L(rt)->sz>k) rt=L(rt); else{ k-=(L(rt)->sz+1); rt=R(rt); } push_down(rt); } splay(rt,fa); } void init(){ cnt=top=0; nil.sz=nil.val=nil.sum=nil.tag=0; null=&nil; root=null; newnode(root,null,0); newnode(R(root),root,0); for(int i=1;i<=n;i++) scanf("%lld",&num[i]); build(L(R(root)),R(root),1,n); push_up(R(root)); push_up(root); } void newnode(node *&x,node *fa,int val){ if(top) x=&nod[st[--top]]; else x=&nod[++cnt]; x->sz=1; x->val=x->sum=val; x->tag=0; x->fa=fa; x->ch[0]=x->ch[1]=null; } void push_down(node *rt){ if(rt->tag){ rt->val+=rt->tag; L(rt)->tag+=rt->tag; R(rt)->tag+=rt->tag; L(rt)->sum+=L(rt)->sz*rt->tag; R(rt)->sum+=R(rt)->sz*rt->tag; rt->tag=0; } } void push_up(node *rt){ rt->sz=L(rt)->sz+R(rt)->sz+1; rt->sum=rt->val+L(rt)->sum+R(rt)->sum; } void build(node *&rt,node *fa,int l,int r){ if(l>r) return ; int mid=(l+r)>>1; newnode(rt,fa,num[mid]); build(L(rt),rt,l,mid-1); build(R(rt),rt,mid+1,r); push_up(rt); } void update(int l,int r,ll x){ rotateto(l-1,null); rotateto(r+1,root); node *rt=L(R(root)); rt->tag+=x; rt->sum+=rt->sz*x; } ll query(int l,int r){ rotateto(l-1,null); rotateto(r+1,root); return L(R(root))->sum; } }spt; int main(){ //freopen("in.txt","r",stdin); while(~scanf("%d%d",&n,&m)){ spt.init(); while(m--){ scanf("%s",str); if(str[0] == 'C'){ int l,r; ll x; scanf("%d%d%lld",&l,&r,&x); spt.update(l,r,x); } else{ int l,r; scanf("%d%d",&l,&r); printf("%lld\n",spt.query(l,r)); } } } return 0; }
poj 3468 A Simple Problem with Integers splay
标签:splay
原文地址:http://blog.csdn.net/u011645923/article/details/43246167