zoukankan      html  css  js  c++  java
  • P2042 [NOI2005]维护数列

    P2042 [NOI2005]维护数列

    splay

    毒瘤模板splay

    自行体会

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<queue> 
    #define re register
    using namespace std;
    template <typename T> inline T min(T &a,T &b) {return a<b ?a:b;}
    template <typename T> inline T max(T &a,T &b) {return a>b ?a:b;}
    template <typename T> inline void read(T &x){
        char c=getchar(); x=0; bool f=1;
        while(!isdigit(c)) f= !f||c=='-' ? 0:1,c=getchar();
        while(isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=getchar();
        x= f ? x:-x;
    }
    template <typename T> inline void output(T x){
        if(!x) {putchar(48); return ;}
        if(x<0) putchar('-'),x=-x;
        int wt[50],l=0;
        while(x) wt[++l]=x%10,x/=10;
        while(l) putchar(wt[l--]+48);
    }
    struct data{
        int fa,ch[2],v,sz,sum,lx,rx,mx,tag,rev;
        void clear(){fa=ch[0]=ch[1]=v=sz=sum=lx=rx=mx=tag=rev=0;}
    }a[500005];
    int n,m,u,rt,val[500005];
    queue <int> lit;
    inline void pdn(int o){
        int lc=a[o].ch[0],rc=a[o].ch[1];
        if(a[o].tag){
            a[o].tag=a[o].rev=0;
            a[lc].tag=a[rc].tag=1;
            a[lc].v=a[rc].v=a[o].v;
            a[lc].sum=a[lc].sz*a[o].v;
            a[rc].sum=a[rc].sz*a[o].v;
            if(a[o].v>=0){
                a[lc].lx=a[lc].rx=a[lc].mx=a[lc].sum;
                a[rc].lx=a[rc].rx=a[rc].mx=a[rc].sum;
            }else{
                a[lc].lx=a[lc].rx=0; a[lc].mx=a[lc].v;
                a[rc].lx=a[rc].rx=0; a[rc].mx=a[rc].v;
            }
        /*    a[lc].mx=max(a[o].v,a[lc].sum);
            a[rc].mx=max(a[o].v,a[rc].sum);
            a[lc].lx=a[lc].rx=max(0,a[lc].sum);
            a[rc].lx=a[rc].rx=max(0,a[rc].sum);*/ //注意不等价!(然鹅并不知道为啥QAQ)
        }if(!a[o].rev) return;
        a[o].rev=0; a[lc].rev^=1; a[rc].rev^=1;
        swap(a[lc].ch[0],a[lc].ch[1]);
        swap(a[rc].ch[0],a[rc].ch[1]);
        swap(a[lc].lx,a[lc].rx);
        swap(a[rc].lx,a[rc].rx);
    }
    inline void mtn(int o){
        if(!o) return;
        int lc=a[o].ch[0],rc=a[o].ch[1];
        a[o].sz=a[lc].sz+a[rc].sz+1;
        a[o].sum=a[lc].sum+a[rc].sum+a[o].v;
        a[o].mx=max(a[lc].rx+a[o].v+a[rc].lx,max(a[lc].mx,a[rc].mx));
        a[o].lx=max(a[lc].lx,a[lc].sum+a[o].v+a[rc].lx);
        a[o].rx=max(a[rc].rx,a[lc].rx+a[o].v+a[rc].sum);
    }
    inline void rte(int x,int &k){
        int y=a[x].fa,z=a[y].fa;
        int l=(a[y].ch[1]==x),r=l^1;
        if(y==k) k=x;
        else a[z].ch[a[z].ch[1]==y]=x;
        a[a[x].ch[r]].fa=y,a[y].fa=x,a[x].fa=z;
        a[y].ch[l]=a[x].ch[r],a[x].ch[r]=y;
        mtn(y); mtn(x);
    }
    inline void splay(int x,int &k){
        for(;x!=k;rte(x,k)){
            int y=a[x].fa,z=a[y].fa;
            if(y!=k){
                if((a[y].ch[0]==x)^(a[z].ch[0]==y)) rte(x,k);
                else rte(y,k);
            }
        }
    }
    inline int find(int x,int k){
        pdn(x);
        int lc=a[x].ch[0],rc=a[x].ch[1];
        if(a[lc].sz+1==k) return x;
        if(a[lc].sz>=k) return find(lc,k);
        else return find(rc,k-a[lc].sz-1);
    }
    inline int split(int x,int k){
        int l=find(rt,x),r=find(rt,x+1+k);
        splay(l,rt); splay(r,a[l].ch[1]);
        return a[r].ch[0];
    }
    //-----↑splay核心↑------ inline
    void build(int &o,int l,int r,int _fa){ //建树 if(l>r) return; if(!o){ if(!lit.empty()) o=lit.front(),lit.pop(); else o=++u; }int mid=l+((r-l)>>1); a[o].sz=1; a[o].fa=_fa; a[o].tag=a[o].rev=0; a[o].sum=a[o].v=a[o].mx=val[mid]; a[o].lx=a[o].rx=max(0,a[o].v); build(a[o].ch[0],l,mid-1,o); build(a[o].ch[1],mid+1,r,o); mtn(o); } inline void ins(int x,int k){ //插入 for(re int i=1;i<=k;++i) read(val[i]); split(x+1,0); int _rt=0,y=a[rt].ch[1]; build(_rt,1,k,y); a[y].ch[0]=_rt; mtn(y); mtn(rt); } inline void reuse(int x){ if(!x) return; reuse(a[x].ch[0]); reuse(a[x].ch[1]); a[x].clear(); lit.push(x); } inline void remov(int x,int k){ //删除 int _rt=split(x,k); int y=a[rt].ch[1]; reuse(_rt); a[y].ch[0]=0; mtn(y); mtn(rt); } inline void modify(int x,int k,int v){ //修改 int _rt=split(x,k); a[_rt].tag=1,a[_rt].v=v; a[_rt].sum=a[_rt].sz*v; a[_rt].lx=a[_rt].rx=max(0,a[_rt].sum); a[_rt].mx=max(v,a[_rt].sum); mtn(a[_rt].fa); mtn(rt); } inline void reverse(int x,int k){ //旋转 int _rt=split(x,k); if(a[_rt].tag) return; a[_rt].rev^=1; swap(a[_rt].ch[0],a[_rt].ch[1]); swap(a[_rt].lx,a[_rt].rx); mtn(a[_rt].fa); mtn(rt); } inline int query(int x,int k){ int _rt=split(x,k); return a[_rt].sum; } int main(){ read(n); read(m); int q1,q2,q3; char opt[14]; val[1]=val[n+2]=-2e9; for(re int i=2;i<=n+1;++i) read(val[i]); build(rt,1,n+2,0); for(re int i=1;i<=m;++i){ scanf("%s",opt); if(opt[0]=='G') read(q1),read(q2),output(query(q1,q2)),putchar(' '); else if(opt[0]=='I') read(q1),read(q2),ins(q1,q2); else if(opt[0]=='D') read(q1),read(q2),remov(q1,q2); else if(opt[0]=='R') read(q1),read(q2),reverse(q1,q2); else{ if(opt[2]=='X') output(a[rt].mx),putchar(' '); else read(q1),read(q2),read(q3),modify(q1,q2,q3); } }return 0; }
  • 相关阅读:
    利用Spring AOP自定义注解解决日志和签名校验
    SpringBoot返回date日期格式化,解决返回为TIMESTAMP时间戳格式或8小时时间差
    @RequestBody配合@JsonFormat注解实现字符串自动转换成Date
    Mysql的时间类型问题
    IntelliJ IDEA使用maven-javadoc-plugin生成Java Doc控制台乱码
    Maven学习笔记(十二)-maven打包之resource配置
    SpringBoot使用@Value从yml文件取值为空--注入静态变量
    cloud server ribbon 自定义策略配置
    JNA 如何 加载多个 存在依赖的 DLL 库
    Remote Desktop File Format
  • 原文地址:https://www.cnblogs.com/kafuuchino/p/9720887.html
Copyright © 2011-2022 走看看