zoukankan      html  css  js  c++  java
  • bzoj:1500: [NOI2005]维修数列

    Description

    Input

    输入的第1 行包含两个数N 和M(M ≤20 000),N 表示初始时数列中数的个数,M表示要进行的操作数目。
    第2行包含N个数字,描述初始时的数列。
    以下M行,每行一条命令,格式参见问题描述中的表格。
    任何时刻数列中最多含有500 000个数,数列中任何一个数字均在[-1 000, 1 000]内。
    插入的数字总数不超过4 000 000个,输入文件大小不超过20MBytes。

    Output

    对于输入数据中的GET-SUM和MAX-SUM操作,向输出文件依次打印结果,每个答案(数字)占一行。

    Sample Input

    9 8
    2 -6 3 5 1 -5 -3 6 3
    GET-SUM 5 4
    MAX-SUM
    INSERT 8 3 -5 7 2
    DELETE 12 1
    MAKE-SAME 3 3 2
    REVERSE 3 6
    GET-SUM 5 4
    MAX-SUM

    Sample Output

    -1
    10
    1
    10

    HINT

    总算切掉了这SPLAY神题……

    主要就是得每次挪个根,把要操作的区间卡成一颗完整的子树就好啦!

    细节还是调了挺久…= =…没办法,弱嘛...>_<

    一开始以为回收空间会很麻烦,结果还是开个queue把删掉的节点遍历一遍放进去就完了。

    #include<queue>
    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    using namespace std;
    
    queue <int> qh;
    int n,m,l,r,p,ch,a[500000],pos,tot,u,c,f;
    inline int read(){
        p=0;ch=getchar();f=1;
        while(ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9') p=p*10+ch-48,ch=getchar();
        return p*f;
    }
    struct tree{
        int l,r,k,f,s,c,sum,lx,rx,mx;
        bool bo;
        tree(){
            bo=f=l=r=sum=0;
            c=1001;
        }
    };
    inline int max(int a,int b){return a>b?a:b;}
    inline int min(int a,int b){return a<b?a:b;}
    struct splay_tree{
        int size,root;
        tree t[500001];
        splay_tree(){
            size=0;root=0;
        }
        inline void update(int p){
            t[p].s=t[t[p].l].s+t[t[p].r].s+1;
            t[p].sum=t[p].k+t[t[p].l].sum+t[t[p].r].sum;
            t[p].lx=max(t[t[p].l].lx,t[t[p].r].lx+t[t[p].l].sum+t[p].k);
            t[p].rx=max(t[t[p].r].rx,t[t[p].l].rx+t[t[p].r].sum+t[p].k);
            t[p].mx=max(max(t[t[p].l].mx,t[t[p].r].mx),t[t[p].l].rx+t[t[p].r].lx+t[p].k);
        }
        inline void pd(int x){
            if (t[x].bo){
                t[t[x].l].bo^=1;t[t[x].r].bo^=1;
                swap(t[x].l,t[x].r);
                swap(t[x].lx,t[x].rx);
                t[x].bo=0;
            }
            if (t[x].c!=1001){
                t[x].k=t[x].c;
                t[t[x].l].c=t[t[x].r].c=t[x].c;
                t[x].sum=t[x].c*t[x].s;
                if (t[x].c>=0) t[x].lx=t[x].rx=t[x].mx=t[x].sum;else t[x].lx=t[x].rx=0,t[x].mx=t[x].c;
                t[x].c=1001;
            }
        }
        inline void ler(int &p){
            int k=t[p].r;
            t[k].f=t[p].f;
            t[p].f=k;
            t[t[k].l].f=p;
            t[p].r=t[k].l;
            t[k].l=p;
            update(p);update(k);
            p=k;
        }
        inline void rir(int &p){
            int k=t[p].l;
            t[k].f=t[p].f;
            t[p].f=k;
            t[t[k].r].f=p;
            t[p].l=t[k].r;
            t[k].r=p;
            update(p);update(k);
            p=k;
        }
        inline void ph(int &p,bool bo){
            if (bo) rir(p);else ler(p);
        }
        inline bool gc(int p){return t[t[p].f].l==p;}
        inline void rot(int p){
            if (t[p].f==root) ph(root,gc(p));else
            if (gc(t[p].f)) ph(t[t[t[p].f].f].l,gc(p));else ph(t[t[t[p].f].f].r,gc(p));
        }
        inline void splay(int p,int f){
            while(t[p].f!=f){
                if (t[t[p].f].f==f) rot(p);else
                if (gc(t[p].f)==gc(p)) rot(t[p].f),rot(p);else rot(p),rot(p);
            }
        }
        inline void build(int &p,int l,int r){
            if (l>r) return;
            if (!qh.empty()) p=qh.front(),qh.pop();else p=++size;
            int mid=(l+r)>>1;
            t[p].k=a[mid];
            build(t[p].l,l,mid-1);
            build(t[p].r,mid+1,r);
            t[t[p].l].f=t[t[p].r].f=p;
            if (l==r){
                t[p].sum=a[mid];
                if (a[mid]>=0) t[p].lx=t[p].rx=a[mid];else t[p].lx=t[p].rx=0;
                t[p].mx=a[mid];
                t[p].s=1;
            }else update(p);
        }
        inline int find(int x,int y){
            pd(x);
            pd(t[x].l);pd(t[x].r);update(x);
            if (t[t[x].l].s<y-1) return find(t[x].r,y-1-t[t[x].l].s);
            if (t[t[x].l].s==y-1) return x;
            return find(t[x].l,y);
        }
        inline void in(int x,int n){
            u=find(root,x+2);x=find(root,x+1);
            splay(x,0);splay(u,x);
            build(t[u].l,1,n);
            t[t[u].l].f=u;
            update(u);update(x);
        }
        inline void reuse(int x){
            if (!x) return;
            qh.push(x);
            reuse(t[x].l);reuse(t[x].r);
            t[x].l=t[x].r=t[x].bo=0;t[x].c=1001;
        }
        inline void del(int x,int n){
            u=find(root,x);x=find(root,x+n+1);
            splay(u,0);splay(x,u);
            reuse(t[x].l);
            t[x].l=0;
            update(x);update(u);
        }
        inline void change(int x,int n,int c){
            u=find(root,x);x=find(root,x+n+1);
            splay(u,0);splay(x,u);
            t[t[x].l].c=c;
            pd(t[x].l);
            update(x);update(u);
        }
        inline void turn(int x,int n){
            u=find(root,x);x=find(root,x+n+1);
            splay(u,0);splay(x,u);
            t[t[x].l].bo^=1;
            pd(t[x].l);
            update(x);update(u);
        }
        inline int qu(int x,int n){
            u=find(root,x);x=find(root,x+n+1);
            splay(u,0);splay(x,u);
            return t[t[x].l].sum;
            update(x);update(u);
        }
    }t;
    char ss[20];
    int main(){
        register int i;
        n=read();m=read();
        for (i=1;i<=n;i++) a[i]=read();
        a[0]=-1e8;a[n+1]=-1e8;
        t.build(t.root,0,n+1);
        while(m--)
        {
            scanf("%s",ss);
            if (ss[0]=='I'){
                pos=read();tot=read();
                for (i=1;i<=tot;i++) a[i]=read();
                t.in(pos,tot);
            }else if (ss[0]=='D') pos=read(),tot=read(),t.del(pos,tot);
            else if (ss[0]=='M'){
                if (ss[2]=='K') pos=read(),tot=read(),c=read(),t.change(pos,tot,c);
                else printf("%d
    ",t.t[t.root].mx);
            }else if (ss[0]=='R') pos=read(),tot=read(),t.turn(pos,tot);
            else if (ss[0]=='G') pos=read(),tot=read(),printf("%d
    ",t.qu(pos,tot));
        }
    }
  • 相关阅读:
    pytorch的函数中的group参数的作用
    pytorch的函数中的dilation参数的作用
    resnet18全连接层改成卷积层
    Pytorch实现UNet例子学习
    MyEclipse中出现Address already in use:JVM_Bind:8080
    为SQL数据库创建登录名和密码
    集合体系
    排序算法及其java实现
    java泛型通配符?
    Arrays.asList的用法
  • 原文地址:https://www.cnblogs.com/Enceladus/p/5228327.html
Copyright © 2011-2022 走看看