zoukankan      html  css  js  c++  java
  • bzoj 1500 维修数列



    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
    这题一看就是splay的水题,边界处理的要死了,第一遍用的splay,第二遍是fhqtreap实在是比splay好打,对于边界我是加了哨兵节点,不过在push_down和change的时候要判断一下,防止哨兵节点被修改,就因为这个被卡了好久,然后就没什么了,Maintain函数要写好一点。注意下细节就好了。

    code:

    #include <bits/stdc++.h>
    #define inf 0x3f3f3f3f
    #define MAXN 500005
    using namespace std;
    int lst[MAXN],n,m;
      
      
    int read(){
        int x=0,f=1;
        char ch=getchar();
        for(;ch>'9'||ch<'0';ch=getchar())if(ch=='-')f=-f;
        for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+(ch^48);
        return x*f;
    }
      
    struct node{
        int r,v,s,filp,lmaxn,rmaxn,maxn,sum;
        bool tag;
        node *ch[2];
      
        void Maintain();
      
        node(){
            r=0;v=0;s=0;
            filp=0;sum=0;tag=0;
            maxn=lmaxn=rmaxn=-inf;
            ch[0]=ch[1]=NULL;
        }
        void push_down();
      
        node(int x);
      
        void* operator new(size_t);
        void operator delete (void* p);
      
    }*null=new node(),*C,*mempool,*root;
      
    typedef pair<node*,node*>pa;
      
    vector<node*>bin;
      
    void change_tag(node *p,int val){
        if(p==null)return;
        p->rmaxn=p->lmaxn=p->maxn=max(val,val*p->s);
        p->sum=val*p->s;
        p->v=val;
        p->tag=1;
    }
      
    void change_filp(node *p){
        if(p==null)return;
        p->filp^=1;
        swap(p->lmaxn,p->rmaxn);
    }
      
    node :: node(int x){
        v=x;r=rand();s=1;
        filp=tag=0;
        lmaxn=rmaxn=maxn=sum=v;
        ch[0]=ch[1]=null;
    }
      
    void node ::  push_down(){
        if(this==null)return;
        if(filp){
            filp^=1;
            change_filp(ch[0]);
            change_filp(ch[1]);
            swap(ch[0],ch[1]);
        }
        if(tag){
            change_tag(ch[0],v);
            change_tag(ch[1],v);
            tag=0;
        }
    }
      
    void node :: Maintain(){
        if(this==null)return;
        push_down();
        s=ch[0]->s+ch[1]->s+1;
        sum=ch[0]->sum+ch[1]->sum+v;
        maxn = max(max(ch[0]->rmaxn,0)+v+max(ch[1]->lmaxn,0),max(ch[0]->maxn,ch[1]->maxn));
        lmaxn = max(ch[0]->lmaxn,ch[0]->sum+v+max(ch[1]->lmaxn,0));
        rmaxn = max(ch[1]->rmaxn,ch[1]->sum+v+max(ch[0]->rmaxn,0));
    }
      
    void* node :: operator new(size_t){
        node *p;
        if(!bin.empty()){
            p=bin.back();
            bin.pop_back();
        }
        else{
            if(C==mempool){
                C = new node[1<<15];
                mempool = C+(1<<15);
            }
            p = C ++;
        }
        return p;
    }
      
    void node :: operator delete(void *p){
        bin.push_back((node*)p);
    }
      
    pa spilt(node *o,int k){
        o->push_down();
        if(!k)return make_pair(null,o);
        if(o==null)return make_pair(null,null);
        if(k<=o->ch[0]->s){
            pa y = spilt(o->ch[0],k);
            o->ch[0]=y.second;
            o->Maintain();
            y.second=o;
            return y;
        }
        else{
            pa y = spilt(o->ch[1],k-o->ch[0]->s-1);
            o->ch[1]=y.first;
            o->Maintain();
            y.first=o;
            return y;
        }
    }
      
    node* merge(node *a,node *b){
        a->push_down();b->push_down();
        if(a==null)return b;
        if(b==null)return a;
        if(a->r>b->r){
            a->ch[1]=merge(a->ch[1],b);
            a->Maintain();
            return a;
        }
        else{
            b->ch[0]=merge(a,b->ch[0]);
            b->Maintain();
            return b;
        }
    }
      
    int Rank(int x){
        node *o=root;
        int ans = 0;
        while(o!=null){
            if(x<=o->v)o=o->ch[0];
            else ans+=o->ch[0]->s+1,o=o->ch[1];
        }
        return ans;
    }
      
    void make_same(int pos,int tot){
        int w = read();
        pa o = spilt(root,pos-1);
        pa x = spilt(o.second,tot);
        change_tag(x.first,w);
        root = merge(o.first,merge(x.first,x.second));
    }
      
    void make_filp(int pos,int tot){
        if(tot==0)return;
        pa o = spilt(root,pos-1);
        pa x = spilt(o.second,tot);
        change_filp(x.first);
        node *tmp=merge(x.first,x.second);
        root = merge(o.first,tmp);
    }
      
    node *build(int l,int r){
        if(l>r)return null;
        int m = l+r>>1;
        node *p=new node(lst[m]);
        p->ch[0]=build(l,m-1);
        p->ch[1]=build(m+1,r);
        p->Maintain();
        return p;
    }
      
    void insert(int pos,int tot){
        for(int i=1;i<=tot;i++)scanf("%d",&lst[i]);
        pa x = spilt(root,pos);
        root = merge(merge(x.first,build(1,tot)),x.second);
    }
      
    void dfs(node *p){
        if(p==null)return;
        dfs(p->ch[0]);
        dfs(p->ch[1]);
        delete p;
    }
      
    void erase(int pos,int tot){
        pa x = spilt(root,pos-1);
        pa y = spilt(x.second,tot);
        dfs(y.first);
        root = merge(x.first,y.second);
    }
      
    inline int max_sum(){
        if(root==null)return 0;
        return root->maxn;
    }
      
    inline void sum(int pos,int tot){
        if(tot==0){printf("0
    ");return;}
        pa x = spilt(root,pos-1);
        pa y = spilt(x.second,tot);
        printf("%d
    ",y.first->sum);
        node *tmp = merge(y.first,y.second);
        root = merge(x.first,tmp);
    }
      
    void dfs1(node *p){
        if(p==null)return;
        dfs1(p->ch[0]);
        printf("%d ",p->v);
        dfs1(p->ch[1]);
    }
      
    int main(){
        root = null;
        n=read(),m=read();
        insert(0,n);
        while(m--){
            char opt[10];
            scanf("%s",opt);
            if(opt[0]=='M'){
                if(opt[2]=='X')printf("%d
    ",max_sum());
                else{ 
                    int pos = read(),tot = read();
                    make_same(pos,tot);
                }
                continue;
            }
            int pos = read(),tot=read();
            if(opt[0]=='I')insert(pos,tot);
            if(opt[0]=='G')sum(pos,tot);
            if(opt[0]=='D')erase(pos,tot);
            if(opt[0]=='R')make_filp(pos,tot);
        }
    }




  • 相关阅读:
    斯坦福大学Andrew Ng教授主讲的《机器学习》公开课观后感
    关于内推,你该知道的点点滴滴
    向大学说拜拜——大学 > 兴趣 + 时间 + 思考 + 实践
    源码浅析:InnoDB聚集索引如何定位到数据的物理位置,并从磁盘读取
    5.7.17版本mysqlbinlog实时拉取的二进制日志不完整的原因分析
    InnoDB的ibd数据文件为什么比data_length+index_length+data_free的总和还要大?
    gh-ost工具在线改表过程的详细解析
    MySQL5.7 使用utf8mb4字符集比latin1字符集性能低25%,你敢信?
    通过slow query log可以查出长时间未提交的事务吗?用实验+源码来揭晓答案
    源码浅析:MySQL一条insert操作,会写哪些文件?包括UNDO相关的文件吗?
  • 原文地址:https://www.cnblogs.com/Cooook/p/7738519.html
Copyright © 2011-2022 走看看