您的位置:首页 > 理论基础 > 数据结构算法

poj 3468 A Simple Problem with Integers 数据结构

2012-05-22 22:29 441 查看
线段树水题

写splay练手

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
#define MAXN 100000+100
struct node
{
long long sum,father,left,right,adt,cnt,num;
};
node tree[MAXN];
int top=0,n,m,root;
long long a[MAXN];
void update(int x)
{
tree[x].sum=tree[tree[x].left].sum+tree[tree[x].right].sum+tree[x].num;
tree[x].cnt=tree[tree[x].left].cnt+tree[tree[x].right].cnt+1;
}
void push_down(int x)
{
tree[tree[x].left].adt+=tree[x].adt;
tree[tree[x].left].num+=tree[x].adt;
tree[tree[x].left].sum+=tree[x].adt*tree[tree[x].left].cnt;
tree[tree[x].right].adt+=tree[x].adt;
tree[tree[x].right].sum+=tree[x].adt*tree[tree[x].right].cnt;
tree[tree[x].right].num+=tree[x].adt;
tree[x].adt=0;
}

void left_rotate(int x)
{
int y=tree[x].father,z=tree[x].left;
if(y==tree[tree[y].father].left) tree[tree[y].father].left=x;
else tree[tree[y].father].right=x;
tree[x].father=tree[y].father;
tree[x].left=y;
tree[y].right=z;
tree[y].father=x;
tree[z].father=y;
update(y); update(x);
}

void right_rotate(int x)
{
int y=tree[x].father,z=tree[x].right;
if(y==tree[tree[y].father].right) tree[tree[y].father].right=x;
else tree[tree[y].father].left=x;
tree[x].father=tree[y].father;
tree[x].right=y;
tree[y].left=z;
tree[y].father=x;
tree[z].father=y;
update(y); update(x);
}

void splay(int rootnew,int x)
{
push_down(x);
int fa=tree[rootnew].father;
while(tree[x].father!=fa)
{
int y=tree[x].father;
int z=tree[y].father;
if(z==fa)
{
if(x==tree[y].left) right_rotate(x);
else left_rotate(x);
break;
}
if(y==tree[z].left)
if(x==tree[y].left) right_rotate(y),right_rotate(x);
else left_rotate(x),right_rotate(x);
else
if(x==tree[y].left) right_rotate(x),left_rotate(x);
else left_rotate(y),left_rotate(x);
}
if(rootnew==root)
root=x;
}
int newnode(int lnum,int rnum,int value)
{
tree[++top].left=lnum; tree[top].right=rnum;
tree[lnum].father=tree[rnum].father=top;
tree[top].num=value;
update(top);
return top;
}
int build_tree(int l,int r)
{
if(l>r) return 0;
int mid=(l+r)/2;
int lnum=build_tree(l,mid-1);
int rnum=build_tree(mid+1,r);
return newnode(lnum,rnum,a[mid]);
}
void find(int root,int pos)
{
int x=root;
while(push_down(x),tree[tree[x].left].cnt+1!=pos)
{
if(pos<=tree[tree[x].left].cnt)
x=tree[x].left;
else
pos-=tree[tree[x].left].cnt+1, x=tree[x].right;
}
splay(root,x);
}
void query(int x,int y)
{
find(root,x-1);
find(tree[root].right,y-x+2);
printf("%lld\n",(tree+tree[tree[root].right].left)->sum);
}
void add(int x,int y,long long z)
{
find(root,x-1);
find(tree[root].right,y-x+2);
int p=tree[tree[root].right].left;
tree[p].sum+=z*tree[p].cnt;
tree[p].adt+=z;
tree[p].num+=z;
}

int main()
{
int i,j;
char c[10];
memset(tree,0,sizeof(tree));
memset(a,0,sizeof(a));
scanf("%d%d",&n,&m);
for(i=2;i<=n+1;i++)
scanf("%lld",a+i);
root=build_tree(1,n+2);
int x,y;
long long z;
for(i=1;i<=m;i++)
{
scanf("%s",c);
if(c[0]=='Q')
{
scanf("%d%d",&x,&y);
query(x+1,y+1);
}
else
{
scanf("%d%d%lld",&x,&y,&z);
add(x+1,y+1,z);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: