您的位置:首页 > 其它

POJ3468/splay树/成段更新

2016-05-14 17:54 295 查看
板子题,正在努力看懂板子。。

http://blog.csdn.net/acm_cxlove/article/details/7815019

http://www.cnblogs.com/kuangbin/archive/2013/04/21/3034081.html

#include <cstdio>
#include <cstring>
#include <algorithm>

#define keyTree (ch[ ch[root][1] ][0])
#define LL long long

using namespace std;

const int maxn = 222222;

struct SpalyTree{
int sz[maxn];
int ch[maxn][2];
int pre[maxn];
int root,top1,top2;
int ss[maxn], que[maxn];

void Rotate(int x,int f)
{
int y = pre[x];
push_down(y);
push_down(x);
ch[y][!f] = ch[x][f];
pre[ ch[x][f]] = y;
pre[x] = pre[y];
if(pre[x]) ch[pre[y] ][ch[pre[y]][1]==y ] = x;
ch[x][f] = y;
pre[y] = x;
push_up(y);
}
void Splay(int x,int goal)
{
push_down(x);
while(pre[x] != goal)
{
if(pre[pre[x] ] == goal)
{
Rotate(x,ch[pre[x] ][0] == x);
}
else
{
int y = pre[x],z = pre[y];
int f = (ch[z][0] == y);
if(ch[y][f] == x)
{
Rotate(x,!f),Rotate(x,f);
}
else
{
Rotate(y,f),Rotate(x,f);
}
}
}
push_up(x);
if(goal == 0) root = x;
}
void RotateTo(int k,int goal)
{
int x = root;
push_down(x);
while(sz[ ch[x][0] ] != k)
{
if(k < sz[ ch[x][0] ])
{
x = ch[x][0];
}
else
{
k -= (sz[ch[x][0] ] + 1);
x = ch[x][1];
}
push_down(x);
}
Splay(x,goal);
}
void erase(int x)
{
int father = pre[x];
int head = 0,tail = 0;
for(que[tail++] = x;head < tail;head++)
{
ss[top2++] = que[head];
if(ch[que[head] ][0]) que[tail++] = ch[que[head] ][0];
if(ch[que[head] ][1]) que[tail++] = ch[que[head] ][1];
}
ch[father ][ch[father][1]==x ] = 0;
push_up(father);
}
void debug(){printf("%d\n",root);Treaval(root);}
void Treaval(int x)
{
if(x)
{
Treaval(ch[x][0]);
printf("结点%2d:左儿子 %2d 右儿子 %2d 父结点 %2d size = %2d ,val = %2d\n",x,ch[x][0],ch[x][1],pre[x],sz[x],val[x]);
Treaval(ch[x][1]);
}
}
void NewNode(int &x,int c)
{
if(top2) x = ss[--top2];
else x = ++top1;
ch[x][0] = ch[x][1] = pre[x] = 0;
sz[x] = 1;

val[x] = sum[x] = c;
add[x] = 0;
}
void push_down(int x)
{
if(add[x])
{
val[x] += add[x];
add[ch[x][0] ] += add[x];
add[ch[x][1] ] += add[x];
sum[ch[x][0] ] += (LL)sz[ch[x][0] ]*add[x];
sum[ch[x][1] ] += (LL)sz[ch[x][1] ]*add[x];
add[x] = 0;
}
}
void push_up(int x)
{
sz[x] = 1+sz[ch[x][0] ] + sz[ch[x][1] ];
sum[x] = add[x] + val[x] + sum[ch[x][0] ] + sum[ch[x][1] ];
}
void makeTree(int &x,int l,int r,int f)
{
if(l > r) return ;
int m = (l+r)>>1;
NewNode(x,num[m]);
makeTree(ch[x][0],l,m-1,x);
makeTree(ch[x][1],m+1,r,x);
pre[x] = f;
push_up(x);
}
void init(int n)
{
ch[0][0] = ch[0][1] = pre[0] = sz[0] = 0;
add[0] = sum[0] = 0;

root = top1 = 0;
NewNode(root, -1);
NewNode(ch[root][1],-1);
pre[top1] = root;
sz[root] = 2;

for(int i=0;i<n;i++)
scanf("%d",&num[i]);
makeTree(keyTree,0,n-1,ch[root][1]);
push_up(ch[root][1]);
push_up(root);
}
void update()
{
int l,r,c;
scanf("%d%d%d",&l,&r,&c);
RotateTo(l-1,0);
RotateTo(r+1,root);
add[keyTree] += c;
sum[keyTree] += (LL)c*sz[keyTree];
}
void query()
{
int l,r;
scanf("%d%d",&l,&r);
RotateTo(l-1,0);
RotateTo(r+1,root);
printf("%lld\n",sum[keyTree]);
}

int num[maxn];
int val[maxn];
int add[maxn];
LL  sum[maxn];
}spt;

int n,m;

int main()
{
while(~scanf("%d%d",&n,&m))
{
spt.init(n);
char op[2];
for(int i=0;i<m;i++)
{
scanf("%s",op);
if(op[0] == 'Q')
{
spt.query();
}
else
spt.update();
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: