线段树的题,但是为了学splay先刷刷水题~~~
Splay的开始在这看的http://dongxicheng.org/structure/splay-tree/
正在把代码风格换成自己的
这道题 首先建立两个节点 表示数组的首尾节点,因为Splay表示区间需要例如a~b
就必须建图为
root==a
rson(a)==b 然后b的lson子树就是a~b
所以我们要求1~n的时候必须有首尾节点
写的时候感觉Push_up比较容易冲突(虽然我没有冲突过….
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<math.h>
#include<queue>
#include<stack>
#include<string>
#include<vector>
#include<map>
#include<set>
using namespace std;
#define rfor(i,a,b) for(i=a;i<=b;++i)
#define lfor(i,a,b) for(i=a;i>=b;--i)
#define sfor(i,a,h) for(i=h[a];i!=-1;i=e[i].next)
#define mem(a,b) memset(a,b,sizeof(a))
#define mec(a,b) memcpy(a,b,sizeof(b))
#define cheak(i) printf("%d ",i)
#define min(a,b) (a>b?b:a)
#define max(a,b) (a>b?a:b)
#define inf 0x3f3f3f3f
#define lowbit(x) (x&(-x))
typedef long long LL;
#define maxn 100005
#define maxm maxn*maxn
#define lson(x) (splay[x].son[0])
#define rson(x) (splay[x].son[1])
struct
{
int add,son[2],fa,val,size;
LL sum;
void init()
{
add=sum=son[0]=son[1]=fa=0;size=0;
}
}splay[maxn];
int tots,root;
int A[maxn];
void init()
{
splay[0].init();
tots=root=0;
}
void NewNode(int &x,int fa,int k)
{
x=++tots;
lson(x)=rson(x)=0;
splay[x].fa=fa;
splay[x].val=splay[x].sum=k;
splay[x].add=0;
splay[x].size=1;
}
void Push_down(int x)
{
if(!splay[x].add) return ;
splay[x].val+=splay[x].add;
splay[lson(x)].add+=splay[x].add;
splay[rson(x)].add+=splay[x].add;
splay[lson(x)].sum+=(LL)splay[lson(x)].size*splay[x].add;
splay[rson(x)].sum+=(LL)splay[rson(x)].size*splay[x].add;
splay[x].add=0;
}
void Push_up(int x)
{
splay[x].size=splay[lson(x)].size+splay[rson(x)].size+1;
splay[x].sum=splay[lson(x)].sum+splay[rson(x)].sum+splay[x].val;
}
void Rotate(int x,int kind)
{
int pre=splay[x].fa;
Push_down(pre);Push_down(x);
splay[pre].son[!kind]=splay[x].son[kind];
splay[splay[x].son[kind]].fa=pre;
if(splay[pre].fa) splay[splay[pre].fa].son[splay[splay[pre].fa].son[1]==pre]=x;
splay[x].fa=splay[pre].fa;
splay[x].son[kind]=pre;
splay[pre].fa=x;
Push_up(pre);
}
void Splay(int x,int goal)
{
Push_down(x);
while(splay[x].fa!=goal)
{
if(splay[splay[x].fa].fa==goal)
Rotate(x,splay[splay[x].fa].son[0]==x);
else
{
int pre=splay[x].fa;
int kind=splay[splay[pre].fa].son[0]==pre;
if(splay[pre].son[kind]==x)
Rotate(x,!kind),Rotate(x,kind);
else Rotate(pre,kind),Rotate(x,kind);
}
}
Push_up(x);
if(!goal) root=x;
}
void build(int &x,int l,int r,int fa)
{
if(l>r) return ;
int mid=(l+r)/2;
NewNode(x,fa,A[mid]);
if(l<mid) build(lson(x),l,mid-1,x);
if(r>mid) build(rson(x),mid+1,r,x);
Push_up(x);
}
void Node_find(int k,int goal)
{
int x=root;
Push_down(x);
while(splay[lson(x)].size!=k)
{
//printf("%d--",x);
if(k<splay[lson(x)].size) x=lson(x);
else
{
k-=splay[lson(x)].size+1;
x=rson(x);
}
Push_down(x);
}
Splay(x,goal);
}
void print_Splay()
{
int i;
rfor(i,1,tots) printf("%d:%d %d %d\n",i,lson(i),rson(i),splay[i].size);
}
LL query(int l,int r)
{
Node_find(l-1,0);
Node_find(r+1,root);
return splay[lson(rson(root))].sum;
}
int main()
{
char str[5];
int n,m,a,b,val,i;
while(~scanf("%d%d",&n,&m))
{
rfor(i,1,n) scanf("%d",&A[i]);
init();
NewNode(root,0,-1);NewNode(rson(root),root,-1);
build(lson(rson(root)),1,n,rson(root));
Push_up(rson(root));Push_up(root);
rfor(i,1,m)
{
scanf("%s",str);
if(str[0]=='Q')
{
scanf("%d%d",&a,&b);
printf("%lld\n",query(a,b));
}
else
{
scanf("%d%d%d",&a,&b,&val);
Node_find(a-1,0);
Node_find(b+1,root);
splay[lson(rson(root))].add+=val;
splay[lson(rson(root))].sum+=val*splay[lson(rson(root))].size;
}
}
}
return 0;
}