POJ 3468 A Simple Problem with Integers (splay)

线段树的题,但是为了学splay先刷刷水题~~~
Splay的开始在这看的http://dongxicheng.org/structure/splay-tree/
正在把代码风格换成自己的
这道题 首先建立两个节点 表示数组的首尾节点,因为Splay表示区间需要例如a~b
就必须建图为
root==a
rson(a)==b 然后b的lson子树就是a~b
所以我们要求1~n的时候必须有首尾节点
写的时候感觉Push_up比较容易冲突(虽然我没有冲突过….

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<math.h>
#include<queue>
#include<stack>
#include<string>
#include<vector>
#include<map>
#include<set>
using namespace std;
#define rfor(i,a,b) for(i=a;i<=b;++i)
#define lfor(i,a,b) for(i=a;i>=b;--i)
#define sfor(i,a,h) for(i=h[a];i!=-1;i=e[i].next)
#define mem(a,b) memset(a,b,sizeof(a))
#define mec(a,b) memcpy(a,b,sizeof(b))
#define cheak(i) printf("%d ",i)
#define min(a,b) (a>b?b:a)
#define max(a,b) (a>b?a:b)
#define inf 0x3f3f3f3f
#define lowbit(x) (x&(-x))
typedef long long LL;
#define maxn 100005
#define maxm maxn*maxn
#define lson(x) (splay[x].son[0])
#define rson(x) (splay[x].son[1])
struct
{
    int add,son[2],fa,val,size;
    LL sum;
    void init()
    {
        add=sum=son[0]=son[1]=fa=0;size=0;
    }
}splay[maxn];
int tots,root;
int A[maxn];
void init()
{
    splay[0].init();
    tots=root=0;
}
void NewNode(int &x,int fa,int k)
{
    x=++tots;
    lson(x)=rson(x)=0;
    splay[x].fa=fa;
    splay[x].val=splay[x].sum=k;
    splay[x].add=0;
    splay[x].size=1;
}
void Push_down(int x)
{
    if(!splay[x].add) return ;
    splay[x].val+=splay[x].add;
    splay[lson(x)].add+=splay[x].add;
    splay[rson(x)].add+=splay[x].add;
    splay[lson(x)].sum+=(LL)splay[lson(x)].size*splay[x].add;
    splay[rson(x)].sum+=(LL)splay[rson(x)].size*splay[x].add;
    splay[x].add=0;
}
void Push_up(int x)
{
    splay[x].size=splay[lson(x)].size+splay[rson(x)].size+1;
    splay[x].sum=splay[lson(x)].sum+splay[rson(x)].sum+splay[x].val;
}
void Rotate(int x,int kind)
{
    int pre=splay[x].fa;
    Push_down(pre);Push_down(x);
    splay[pre].son[!kind]=splay[x].son[kind];
    splay[splay[x].son[kind]].fa=pre;
    if(splay[pre].fa) splay[splay[pre].fa].son[splay[splay[pre].fa].son[1]==pre]=x;
    splay[x].fa=splay[pre].fa;
    splay[x].son[kind]=pre;
    splay[pre].fa=x;
    Push_up(pre);
}
void Splay(int x,int goal)
{
    Push_down(x);
    while(splay[x].fa!=goal)
    {
        if(splay[splay[x].fa].fa==goal)
        Rotate(x,splay[splay[x].fa].son[0]==x);
        else
        {
            int pre=splay[x].fa;
            int kind=splay[splay[pre].fa].son[0]==pre;
            if(splay[pre].son[kind]==x)
            Rotate(x,!kind),Rotate(x,kind);
            else Rotate(pre,kind),Rotate(x,kind);
        }
    }
    Push_up(x);
    if(!goal) root=x;
}
void build(int &x,int l,int r,int fa)
{
    if(l>r) return ;
    int mid=(l+r)/2;
    NewNode(x,fa,A[mid]);
    if(l<mid) build(lson(x),l,mid-1,x);
    if(r>mid) build(rson(x),mid+1,r,x);
    Push_up(x);
}
void Node_find(int k,int goal)
{
    int x=root;
    Push_down(x);
    while(splay[lson(x)].size!=k)
    {
        //printf("%d--",x);
        if(k<splay[lson(x)].size) x=lson(x);
        else
        {
            k-=splay[lson(x)].size+1;
            x=rson(x);
        }
        Push_down(x);
    }
    Splay(x,goal);
}
void print_Splay()
{
    int i;
    rfor(i,1,tots) printf("%d:%d %d %d\n",i,lson(i),rson(i),splay[i].size);
}
LL query(int l,int r)
{
    Node_find(l-1,0);
    Node_find(r+1,root);
    return splay[lson(rson(root))].sum;
}
int main()
{
    char str[5];
    int n,m,a,b,val,i;
    while(~scanf("%d%d",&n,&m))
    {
        rfor(i,1,n) scanf("%d",&A[i]);
        init();
        NewNode(root,0,-1);NewNode(rson(root),root,-1);
        build(lson(rson(root)),1,n,rson(root));
        Push_up(rson(root));Push_up(root);
        rfor(i,1,m)
        {
            scanf("%s",str);
            if(str[0]=='Q')
            {
                scanf("%d%d",&a,&b);
                printf("%lld\n",query(a,b));
            }
            else
            {
                scanf("%d%d%d",&a,&b,&val);
                Node_find(a-1,0);
                Node_find(b+1,root);
                splay[lson(rson(root))].add+=val;
                splay[lson(rson(root))].sum+=val*splay[lson(rson(root))].size;
            }
        }
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值