poj-3468-A Simple Problem with Integers-splay树

原本应该是线段树板刷的题目,现在用splay tree来做一下。就当练练手。

建立初始树的时候按照顺序建立的二叉树。

每个节点存储的信息:

int pre[maxn];     当前节点的前驱

int ch[maxn][2];当前节点的左右子树

int val[maxn];当前节点的值

int size[maxn];当前节点的子树的节点个数

int add[maxn];当前节点的子树被增加的值

LL sum[maxn];当前节点的子树的总值

当Q X Y的时候,就把x-1节点设置成根节点。y+1节点设置成根节点的右子树。

那么sum[ch[ch[root][1]][0]]即为结果。

当C X Y k的时候,就把x-1节点设置成根节点。y+1节点设置成根节点的右子树。

然后add[ch[ch[root][1]][0]]+=k;

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
using namespace std;
#define maxn 110000
#define LL long long
struct splaytree
{
    int a[maxn];
    int pre[maxn];
    int ch[maxn][2];
    int val[maxn];
    int root,tot,n;
    int size[maxn];
    int add[maxn];
    LL sum[maxn];
    void init(){
        memset(pre,0,sizeof(pre));
        memset(ch,0,sizeof(ch));
        memset(size,0,sizeof(size));
        memset(add,0,sizeof(add));
        memset(sum,0,sizeof(sum));
        memset(val,0,sizeof(val));
        root=tot=0;
        start();
    }
    void newnode(int &r,int father,int k){
        r=++tot;
        pre[r]=father;
        add[r]=0;
        sum[r]=k;
        val[r]=k;
        ch[r][0]=ch[r][1]=0;
        size[r]=1;
    }
    void push_up(int x){
        size[x]=size[ch[x][1]]+size[ch[x][0]]+1;
        sum[x]=sum[ch[x][1]]+sum[ch[x][0]]+add[x]+val[x];
    }
    void push_down(int x){
        val[x]+=add[x];
        add[ch[x][1]]+=add[x];
        add[ch[x][0]]+=add[x];
        sum[ch[x][1]]+=(LL)add[x]*size[ch[x][1]];
        sum[ch[x][0]]+=(LL)add[x]*size[ch[x][0]];
        add[x]=0;
    }
    void rot(int x,int kind){
        int y=pre[x];
        push_down(x);
        push_down(y);
        ch[y][!kind]=ch[x][kind];
        pre[ch[x][kind]]=y;
        if(pre[y])ch[pre[y]][ch[pre[y]][1]==y]=x;
        pre[x]=pre[y];
        ch[x][kind]=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)rot(x,ch[pre[x]][0]==x);
            else{
                int y=pre[x];
                int kind=ch[pre[y]][0]==y;
                if(ch[y][kind]==x){
                    rot(x,!kind);
                    rot(x,kind);
                }
                else{
                    rot(y,kind);
                    rot(x,kind);
                }
            }
        }
        push_up(x);
        if(goal==0)root=x;
    }
    void rotto(int x,int goal){
        int r=root;
        push_down(r);
        while(size[ch[r][0]]!=x){
            if(x<size[ch[r][0]])r=ch[r][0];
            else{
                x=x-size[ch[r][0]]-1;
                r=ch[r][1];
            }
            push_down(r);
        }
        splay(r,goal);
    }
    void update(int l,int r){
        int k;
        scanf("%d",&k);
        rotto(l-1,0);
        rotto(r+1,root);
        add[ch[ch[root][1]][0]]+=k;
        sum[ch[ch[root][1]][0]]+=size[ch[ch[root][1]][0]]*k;
    }
    LL query(int l,int r){
        rotto(l-1,0);
        rotto(r+1,root);
        return sum[ch[ch[root][1]][0]];
    }
    void buildtree(int &x,int l,int r,int father){
        if(l>r)return;
        int mid=(l+r)/2;
        newnode(x,father,a[mid]);
        if(l<mid)buildtree(ch[x][0],l,mid-1,x);
        if(r>mid)buildtree(ch[x][1],mid+1,r,x);
        push_up(x);
    }
    void start(){
        for(int i=0;i<n;i++)scanf("%d",&a[i]);
        newnode(root,0,-1);
        newnode(ch[root][1],root,-1);
        size[root]=2;
        buildtree(ch[ch[root][1]][0],0,n-1,ch[root][1]);
        push_up(ch[root][1]);
        push_up(root);
    }
}T;
int main()
{
    int n,q;
    while(~scanf("%d%d",&n,&q))
    {
        T.n=n;
        T.init();
        while(q--){
            char str[10];
            int x,y;
            scanf("%s%d%d",str,&x,&y);
            if(str[0]=='Q')
                printf("%lld\n",T.query(x,y));
            else
                T.update(x,y);
        }
    }
    return 0;
}













你可能感兴趣的:(poj-3468-A Simple Problem with Integers-splay树)