POJ 3468 A Simple Problem with Integers Splay tree&Segment tree(二)

2014-11-24 11:26:10 · 作者: · 浏览: 1
tmp=ch[tmp][1];
return key[x]-key[tmp];
}
//找后继,即右子树的最左结点
int get_next(int x){
int tmp=ch[x][1];
if(tmp==0) return inf;
while(ch[tmp][0])
tmp=ch[tmp][0];
return key[tmp]-key[x];
}
//查询[l,r]之间的和
LL Query(int l,int r){
RotateTo(l-1,0);
RotateTo(r+1,root);
return sum[Key_value];
}
//更新
void Update(int l,int r){
int k;
scanf("%d",&k);
RotateTo(l-1,0);
RotateTo(r+1,root);
add[Key_value]+=k;
sum[Key_value]+=size[Key_value]*k;
}
int a[N];
//建树,中间结点先建立,然后分别对区间两端在左右子树建立
void BulidTree(int &x,int l,int r,int father){
if(l>r)
return;
int mid=(l+r)/2;
NewNode(x,father,a[mid]);
if(l BulidTree(ch[x][0],l,mid-1,x);
if(r>mid)
BulidTree(ch[x][1],mid+1,r,x);
Push_Up(x);
}
void Init(){
for(int i=0;i scanf("%d",&a[i]);
ch[0][0]=ch[0][1]=pre[0]=size[0]=0;
add[0]=sum[0]=0;
root=tot1=0;
NewNode(root,0,-1);
NewNode(ch[root][1],root,-1); //头尾各加入一个空位
size[root]=2;
BulidTree(Key_value,0,n-1,ch[root][1]); //让所有数据夹在两个-1之间
Push_Up(ch[root][1]);
Push_Up(root);
}
int main(){
while(scanf("%d%d",&n,&q)!=EOF){
Init();
while(q--){
char str[10];
int x,y;
scanf("%s%d%d",str,&x,&y);
if(str[0]=='Q')
printf("%lld\n",Query(x,y));
else
Update(x,y);
}
}
return 0;
}

以下为Segment tree
[cpp]
#include
#include
using namespace std;
struct line{
int left,right,mid;
int add;
long long sum;
}L[500005];
long long a[500005],n;
long long bulid(int step,int l,int r){
L[step].left=l;
L[step].right=r;
L[step].mid=(l+r)/2;
L[step].add=0;
if(l==r)
return L[step].sum=a[l];
return L[step].sum=bulid(2*step,l,(l+r)/2)+bulid(2*step+1,(l+r)/2+1,r);
}
void update(int step,long long x,long long y,long long z){
if(x <= L[step].left && y >= L[step].right) {
L[step].add += z;
L[step].sum += (long long )(L[step].right-L[step].left+1)*z;
return ;
}
if(L[step].add) {
L[2*step].sum += (long long )(L[step].mid-L[step].left+1)*L[step].add;
L[2*step+1].sum+=(long long )(L[step].right-L[step].mid)*L[step].add;
L[2*step].add += L[step].add;
L[2*step+1].add+=L[step].add;
L[step].add = 0;
}
if(x <= L[step].mid) update(2*step,x,y,z);
if(L[step].mid L[step].sum=L[2*step].sum +L[2*step+1].sum;
}
long long query(int step,long long x,long long y){
if(L[step].left==x&&L[step].right==y)
return L[step].sum;
if(L[step].add) {
L[2*step].sum += (long long )(L[step].mid-L[step].left+1) * L[step].add;
L[2*step+1].sum += (long long )(L[step].right-L[step].mid) * L[step].add;
L[2*step].add+=L[step].add;
L[2*step+1].add+=L[step].add;
L[step].add=0;
}
if(L[step].mid return query(2*step+1,x,y);
else
if(L[step].mid>=y)
return query(2*step,x,y);
else
return query(2*step,x,L[step].mid)+query(2*step+1,L[step].mid+1,y);
}
int main(){
int m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]);
char str[5];
bulid(1,1,n);
while(m--){
s