FHQ_Treap 90 TLE求调
查看原帖
FHQ_Treap 90 TLE求调
755574
ZXZ_楼主2024/5/4 17:54
#include<bits/stdc++.h>
#define N 500001
using namespace std;
unsigned long long seed=1;
int n,m;
struct FHQ_Treap{
    int rt,now;
    struct Tree{int l,r,siz,val,rnd;}tr[N];
    void pushup(int x){tr[x].siz=tr[tr[x].l].siz+tr[tr[x].r].siz+1;}
    int newnode(int val){
        tr[++now].val=val;
        tr[now].rnd=rand();
        tr[now].siz=1;
        return now;
    }
    void split(int p,int v,int& x,int& y){
        if(!p){x=y=0;return;}
        if(tr[p].val<=v){
            x=p;
            split(tr[p].r,v,tr[p].r,y);
        }else{
            y=p;
            split(tr[p].l,v,x,tr[p].l);
        }
        pushup(p);
    }
    int merge(int x,int y){
        if(!x||!y)return x+y;
        if(tr[x].rnd<tr[y].rnd){
            tr[x].r=merge(tr[x].r,y);
            pushup(x);
            return x;
        }else {
            tr[y].l=merge(x,tr[y].l);
            pushup(y);
            return y;
        }
    }
    void insert(int val){
        int x,y;
        split(rt,val,x,y);
        int z=newnode(val);
        rt=merge(merge(x,z),y);
    }
    void del(int val){
        int x,y,z;
        split(rt,val,x,z);
        split(x,val-1,x,y);
        y=merge(tr[y].l,tr[y].r);
        rt=merge(merge(x,y),z);
    }
    int rnk(int val){
        int x,y,res;
        split(rt,val-1,x,y);
        res=tr[x].siz+1;
        rt=merge(x,y);
        return res;
    }
    int topk(int p,int k){
        int lsiz=tr[tr[p].l].siz;
        if(k==lsiz+1)return tr[p].val;
        else if(k<=lsiz)return topk(tr[p].l,k);
        else return topk(tr[p].r,k-lsiz-1);
    }
    int getpre(int val){
        int x,y,res;
        split(rt,val-1,x,y);
        res=topk(x,tr[x].siz);
        rt=merge(x,y);
        return res;
    }
    int getsuc(int val){
        int x,y,res;
        split(rt,val,x,y);
        res=topk(y,1);
        rt=merge(x,y);
        return res;
    }
}T;
struct FHQ_Treep_Interval{
    int rt,now,insters[N];
    stack<int> rub;
    struct node{
        int l,r,siz,val,rnd,tag,cval,rev;
        int sum,mpre,msuc,msum;
    }tr[N];
    inline void pushup(int x){
        tr[x].siz=tr[tr[x].l].siz+tr[tr[x].r].siz+1;
        tr[x].sum=tr[tr[x].l].sum+tr[tr[x].r].sum+tr[x].val;
        tr[x].mpre=max({tr[tr[x].l].sum+tr[x].val+tr[tr[x].r].mpre,tr[tr[x].l].mpre,0});
        tr[x].msuc=max({tr[tr[x].l].msuc+tr[x].val+tr[tr[x].r].sum,tr[tr[x].r].msuc,0});
        tr[x].msum=max(tr[x].val+tr[tr[x].l].msuc+tr[tr[x].r].mpre,tr[x].val);
        if(tr[x].l)tr[x].msum=max(tr[x].msum,tr[tr[x].l].msum);
        if(tr[x].r)tr[x].msum=max(tr[x].msum,tr[tr[x].r].msum);
    }
    inline int build(int l,int r){
        if(l==r)return newnode(insters[l]);
        int mid=l+r>>1;
        return merge(build(l,mid),build(mid+1,r));
    }
    inline void insert1(int k,int tot){
        int x,y;
        split(rt,k,x,y);
        int z=build(1,tot);
        rt=merge(merge(x,z),y);
    }
    inline void cover(int x){
        if(!tr[x].tag)return;
        tr[x].val=tr[x].cval;
        tr[x].sum=tr[x].cval*tr[x].siz;
        tr[x].mpre=tr[x].msuc=max(0,tr[x].sum);
        tr[x].msum=max(tr[x].cval,tr[x].sum);
        tr[tr[x].l].tag=tr[x].tag;
        tr[tr[x].r].tag=tr[x].tag;
        tr[tr[x].l].cval=tr[x].cval;
        tr[tr[x].r].cval=tr[x].cval;
        if(tr[x].l)pushdown(tr[x].l);
        if(tr[x].r)pushdown(tr[x].r);
        tr[x].tag=0;
        tr[x].cval=0;
    }
    inline void dorev(int x){
        if(!tr[x].rev)return;
        swap(tr[x].l,tr[x].r);
        swap(tr[x].mpre,tr[x].msuc);
        tr[tr[x].l].rev^=1;
        tr[tr[x].r].rev^=1;
        tr[x].rev=0;
        return;
    }
    inline void pushdown(int x){
        if(!x)return;
        dorev(x);
        if(tr[x].l)dorev(tr[x].l);
        if(tr[x].r)dorev(tr[x].r);
        cover(x);
        if(tr[x].l)cover(tr[x].l);
        if(tr[x].r)cover(tr[x].r);
    }
    inline int newnode(int val){
        int t;
        if(!rub.empty())t=rub.top(),rub.pop();
        else t=++now;
        memset(&tr[t],0,sizeof(tr[t]));
        tr[t].siz=1;
        tr[t].sum=tr[t].msum=tr[t].val=val;
        tr[t].mpre=tr[t].msuc=max(0,val);
        tr[t].rnd=rand();
        return t;
    }
    inline void help_split(int& x,int& y,int& z,int k,int tot){
        int l=k,r=k+tot-1;
        split(rt,r,x,z);
        split(x,l-1,x,y);
    }
    inline void split(int p,int k,int& x,int& y){
        if(!p){x=y=0;return;}
        pushdown(p);
        if(tr[tr[p].l].siz<k){
            x=p;
            k-=tr[tr[p].l].siz+1;
            split(tr[p].r,k,tr[p].r,y);
        }else{
            y=p;
            split(tr[p].l,k,x,tr[p].l);
        }
        pushup(p);
    }
    inline int merge(int x,int y){
        if(!x||!y)return x+y;
        if(tr[x].rnd<tr[y].rnd){
            pushdown(x);
            tr[x].r=merge(tr[x].r,y);
            pushup(x);
            return x;
        }
        else{
            pushdown(y);
            tr[y].l=merge(x,tr[y].l);
            pushup(y);
            return y;
        }
    }
    inline void insert(int k,int tot){
        int x,y;
        split(rt,k,x,y);
        for(int i=1;i<=tot;i++)
            x=merge(x,newnode(insters[i]));
        rt=merge(x,y);
    }
    inline void recl(int p){
        if(!p)return;
        rub.push(p);
        recl(tr[p].l),recl(tr[p].r);
    }
    inline void del(int k,int tot){
        int x,y,z;
        help_split(x,y,z,k,tot);
        recl(y);
        rt=merge(x,z);
    }
    inline int getsum(int k,int tot){
        int x,y,z,res;
        help_split(x,y,z,k,tot);
        res=tr[y].sum;
        rt=merge(merge(x,y),z);
        return res;
    }
    inline int maxsum(){return tr[rt].msum;}
    inline void update_s(int k,int tot,int c){
        int x,y,z;
        help_split(x,y,z,k,tot);
        tr[y].tag=1;
        tr[y].cval=c;
        cover(y);
        rt=merge(merge(x,y),z);
        return;
    }
    inline void reverse(int k,int tot){
        int x,y,z;
        help_split(x,y,z,k,tot);
        tr[y].rev^=1;
        dorev(y);
        rt=merge(merge(x,y),z);
    }
    inline void build1(int val){rt=merge(rt,newnode(val));}
    inline void output(int p) {
        if(!p)return;
        pushdown(p);
        output(tr[p].l);
        printf("%d ", tr[p].val);
        output(tr[p].r);
    }
}T1;
char s[21];
int main(){
    srand(time(0));
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        int x;
        scanf("%d",&x);
        T1.build1(x);
    }
    while(m--){
        scanf("%9s",s);
        int l,r,tot,k,c;
        if(s[0]=='I'){
            scanf("%d%d",&k,&tot);
            for(int i=1;i<=tot;i++)
                scanf("%d",&T1.insters[i]);
            T1.insert1(k,tot);
            // //DEBUG
            // printf("opt %d\n",m);
            // T1.output(T1.rt);
            // puts("");
        }else if(s[0]=='D'){
            scanf("%d%d",&k,&tot);
            T1.del(k,tot);
            // //DEBUG
            // printf("opt %d\n",m);
            // T1.output(T1.rt);
            // puts("");
        }else if(s[0]=='M'&&s[2]=='K'){
            scanf("%d%d%d",&k,&tot,&c);
            T1.update_s(k,tot,c);
            // //DEBUG
            // printf("opt %d\n",m);
            // T1.output(T1.rt);
            // puts("");
        }else if(s[0]=='R'){
            scanf("%d%d",&k,&tot);
            T1.reverse(k,tot);
            // //DEBUG
            // printf("opt %d\n",m);
            // T1.output(T1.rt);
            // puts("");
        }else if(s[0]=='G'){
            scanf("%d%d",&k,&tot);
            printf("%d\n",T1.getsum(k,tot));
            // //DEBUG
            // printf("opt %d\n",m);
            // T1.output(T1.rt);
            // puts("");
        }else if(s[0]=='M')printf("%d\n",T1.maxsum());
    }
}
2024/5/4 17:54
加载中...