40pts splay 求调
查看原帖
40pts splay 求调
576817
Lyrella楼主2022/2/15 12:06
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
 
#define MAXN 500005
#define INF 1<<30
using namespace std;
 
struct Node
{
        int son[2],l,r,m,k,t1,t2,s,sum,fa;
};
 
Node tree[MAXN];
int m,n,root,a[MAXN];
char now[10];
queue<int> Q;
 
void plus1(int now,int val)
{
        if (!now) return;
        tree[now].k=val,tree[now].t1=1,tree[now].sum=tree[now].k*tree[now].s;
        if (tree[now].k>0) tree[now].l=tree[now].r=tree[now].m=tree[now].sum; 
        else tree[now].l=tree[now].r=tree[now].m=tree[now].k;
}
 
void plus2(int now)
{
        if (!now) return;
        swap(tree[now].son[0],tree[now].son[1]),tree[now].t2^=1;
        swap(tree[now].l,tree[now].r);
}
 
void push(int now)
{
        if (!now) return;
        if (tree[now].t1) plus1(tree[now].son[0],tree[now].k),plus1(tree[now].son[1],tree[now].k),tree[now].t1=0;
        if (tree[now].t2) plus2(tree[now].son[0]),plus2(tree[now].son[1]),tree[now].t2=0;
}
 
void update(int now)
{
        if (!now) return;
        push(now);
        int lson=tree[now].son[0],rson=tree[now].son[1];
        tree[now].s=tree[lson].s+tree[rson].s+1;
        tree[now].sum=tree[lson].sum+tree[rson].sum+tree[now].k;
        tree[now].l=max(tree[lson].l,tree[lson].sum+tree[now].k+max(tree[rson].l,0));
        tree[now].r=max(tree[rson].r,tree[rson].sum+tree[now].k+max(tree[lson].r,0)); 
        tree[now].m=max(max(tree[lson].m,tree[rson].m),tree[now].k+max(tree[lson].r,0)+max(tree[rson].l,0));
}
 
void rotate(int now)
{
        int fa=tree[now].fa,gfa=tree[fa].fa,q=(tree[fa].son[1]==now),son=tree[now].son[q^1];
        if (gfa) tree[now].fa=gfa,tree[gfa].son[tree[gfa].son[1]==fa]=now;
        else tree[now].fa=0,root=now;
        tree[fa].son[q]=son; if (son) tree[son].fa=fa;
        tree[fa].fa=now,tree[now].son[q^1]=fa;
        update(fa),update(now);
}
 
void splay(int now)
{
        int k=0;
        for (int x=now;x;x=tree[x].fa) { k++; a[k]=x; }
        for (int i=k;i>=1;i--) push(a[i]);
        while (tree[now].fa) rotate(now);
}
 
void build(int now,int l,int r)
{
        int mid=(l+r)>>1;
        if (l<mid) tree[now].son[0]=Q.front(),Q.pop(),build(tree[now].son[0],l,mid-1),tree[tree[now].son[0]].fa=now;
        scanf("%d",&tree[now].k);
        if (mid<r) tree[now].son[1]=Q.front(),Q.pop(),build(tree[now].son[1],mid+1,r),tree[tree[now].son[1]].fa=now;
        update(now);
}
        
int Rank(int q)
{
        int now=root;
        while (now)
        {
                push(now);
                if (tree[tree[now].son[0]].s+1==q) return now;
                if (tree[tree[now].son[0]].s>=q) now=tree[now].son[0];
                else q-=tree[tree[now].son[0]].s+1,now=tree[now].son[1];
        }
        return 0;
}
 
void ins()
{
        int pos,tot,l,r,root; scanf("%d %d",&pos,&tot);
        l=Rank(pos),r=Rank(pos+1); splay(l),splay(r);
        root=Q.front(),Q.pop(),build(root,1,tot);
        if (l) tree[l].son[1]=root,tree[root].fa=l;
        else   tree[r].son[0]=root,tree[root].fa=r;
        update(l),update(r);
}
 
void DFS(int now)
{
        if (tree[now].son[0]) DFS(tree[now].son[0]);
        if (tree[now].son[1]) DFS(tree[now].son[1]);
        Q.push(now),memset(tree+now,0,sizeof(tree[now]));
}
 
void del()
{
        int pos,tot,l,r; scanf("%d %d",&pos,&tot);
        l=Rank(pos-1),r=Rank(pos+tot); splay(l),splay(r);
        if (l) DFS(tree[l].son[1]),tree[l].son[1]=0;
        else   DFS(tree[r].son[0]),tree[r].son[0]=0;
        update(l),update(r);
}
 
void makeSame()
{
        int pos,tot,c,l,r; scanf("%d %d %d",&pos,&tot,&c);
        l=Rank(pos-1),r=Rank(pos+tot); splay(l),splay(r);
        if (l) plus1(tree[l].son[1],c); else plus1(tree[r].son[0],c);
        update(l),update(r);
}
 
void reverse()
{
        int pos,tot,l,r; scanf("%d %d",&pos,&tot);
        l=Rank(pos-1),r=Rank(pos+tot); splay(l),splay(r);
        if (l) plus2(tree[l].son[1]); else if (r) plus2(tree[r].son[0]); else plus2(root);
        update(l),update(r);
}
 
int getSum()
{
        int pos,tot,l,r; scanf("%d %d",&pos,&tot);
        l=Rank(pos-1),r=Rank(pos+tot); splay(l),splay(r);
        if (l) return tree[tree[l].son[1]].sum;
        else return tree[tree[r].son[0]].sum;
}
        
int maxSum() { return tree[root].m; }
 
void init()
{
        //freopen("1500.in","r",stdin);
        //freopen("1500.out","w",stdout);
        scanf("%d %d",&n,&m);
        for (int i=1;i<=MAXN;i++) Q.push(i);
        tree[0].l=tree[0].r=tree[0].m=-INF;
        root=Q.front(),Q.pop(),build(root,1,n);
}
 
int main()
{
        init();
        for (int i=1;i<=m;i++)
        {
                scanf("%s",&now);
                if (now[0]=='I') ins();
                else if (now[0]=='D') del();
                else if (now[2]=='K') makeSame(); 
                else if (now[0]=='R') reverse();
                else if (now[0]=='G') printf("%d\n",getSum());
                else printf("%d\n",maxSum());
        }
        return 0;
}
2022/2/15 12:06
加载中...