偷偷摸来SPLAY指针板子

这是洛谷的P4146 系列终结者

// luogu-judger-enable-o2
#include<bits/stdc++.h>
using namespace std;
struct node
{
    node *son[2],*father;
    int maxa,tag,num,flag,size;
}pool[1000005],*tail=pool,*root,*zero;
int n,m,shu1,shu2,shu3,shu4;
void update(node *nd)
{
    nd->size=nd->son[0]->size+nd->son[1]->size+1;
    if(nd->son[0]!=zero&&nd->son[1]!=zero)
    nd->maxa=max(nd->num,max(nd->son[0]->maxa,nd->son[1]->maxa));
    else if(nd->son[0]!=zero)
    nd->maxa=max(nd->num,nd->son[0]->maxa);
    else if(nd->son[1]!=zero)
    nd->maxa=max(nd->num,nd->son[1]->maxa);
    else nd->maxa=nd->num;
}
void pushdown(node *nd)
{
    if(nd->flag)
    {
        swap(nd->son[0],nd->son[1]);
        if(nd->son[0]!=zero)
        nd->son[0]->flag^=1;
        if(nd->son[1]!=zero)
        nd->son[1]->flag^=1;
        nd->flag=0;
    }
    if(nd->tag)
    {
        if(nd->son[0]!=zero)
        {
            nd->son[0]->maxa+=nd->tag;
            nd->son[0]->num+=nd->tag;
            nd->son[0]->tag+=nd->tag;
        }
        if(nd->son[1]!=zero)
        {
            nd->son[1]->maxa+=nd->tag;
            nd->son[1]->num+=nd->tag;
            nd->son[1]->tag+=nd->tag;
        }
        nd->tag=0;
    }
}
void init()
{
    zero=tail++;
    zero->son[0]=zero->son[1]=zero->father=zero;
    zero->num=zero->maxa=zero->size=zero->tag=0;
}
node *build(int l,int r)
{
    if(l>r) return zero;
    node *nd=tail++;
    nd->maxa=nd->num=0;
    int mid=(l+r)>>1;
    nd->son[0]=build(l,mid-1);
    nd->son[1]=build(mid+1,r);
    if(nd->son[0]!=zero)
    nd->son[0]->father=nd;
    if(nd->son[1]!=zero)
    nd->son[1]->father=nd;
    update(nd);
    return nd;
}
node *find(int x)
{
    node *now=root;
    while(1)
    {
        pushdown(now);
        if(now->son[0]->size>=x) now=now->son[0];
        else if(now->son[0]->size+1==x) return now;
        else x-=now->son[0]->size+1,now=now->son[1];
    }
}
void rotate(node *nd)
{
    node *p=nd->father;
    node *pp=p->father;
    int another=pp->son[1]==p;
    int kind=(p->son[0]==nd);
    node *s=nd->son[kind];
    if(s!=zero)
    s->father=p;
    p->son[!kind]=s;
    if(pp!=zero)
    nd->father=pp;
    else root=nd,nd->father=zero;
    if(pp!=zero)
    pp->son[another]=nd;
    nd->son[kind]=p;
    p->father=nd;
    update(p);
    update(nd);
}
void splay(node *nd,node *pre)
{
    while(nd->father!=pre)
    {
        node *p=nd->father;
        if(p->father==pre)
        {
            rotate(nd);
            break;
        }
        node *pp=p->father;
        if((pp->son[1]==p)==(p->son[1]==nd))
        {
            rotate(p);
            rotate(nd);
        }
        else 
        {
            rotate(nd);
            rotate(nd);
        }
    }
}
void modify(int l,int r,int delta)
{
    node *r1=find(l);
    node *r2=find(r+2);
    splay(r1,zero);
    splay(r2,r1);
    r2->son[0]->tag+=delta;
    r2->son[0]->num+=delta;
    r2->son[0]->maxa+=delta;
}
void reverse(int l,int r)
{
    node *r1=find(l);
    node *r2=find(r+2);
    splay(r1,zero);
    splay(r2,r1);
    r2->son[0]->flag^=1;
}
int query(int l,int r)
{
    node *r1=find(l);
    node *r2=find(r+2);
    splay(r1,zero);
    splay(r2,r1);
    return r2->son[0]->maxa;
}
int main()
{
    cin>>n>>m;
    init();
    root=build(1,n+2);
    root->father=zero;
    for(int i=1;i<=m;i++)
    {
        scanf("%d",&shu1);
        if(shu1==1)
        {
            scanf("%d%d%d",&shu2,&shu3,&shu4);
            modify(shu2,shu3,shu4);
        }
        else if(shu1==2)
        { 
            scanf("%d%d",&shu2,&shu3);
            reverse(shu2,shu3);
        }
        else 
        {
            scanf("%d%d",&shu2,&shu3);
            printf("%d\n",query(shu2,shu3));
        }
    }
    return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值