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

来源:互联网 发布:java简历项目经验案例 编辑:程序博客网 时间:2024/05/18 03:10

原本应该是线段树板刷的题目,现在用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 longstruct 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;}


0 0
原创粉丝点击