zoukankan      html  css  js  c++  java
  • bzoj4864: [BeiJing 2017 Wc]神秘物质

    这道题维护区间极差的最小值 只有长度为二的区间有贡献 这个可以尝试画一下 自己想想 这样之后维护的值有 区间最小值 区间最大值 以及区间内长度为二的区间差的最小值 区间大小 点本身的值。 注意要看你维护的区间差在区间左点还是右点 这在查询min的时候很重要 剩下的自己看把 代码不算长的了 虽然有点慢 换成结构体应该会快很多 

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int M=250000,inf=0x3f3f3f3f;
    int read(){
        int ans=0,f=1,c=getchar();
        while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
        while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
        return ans*f;
    }
    int n,m,root,sum;
    int c[M][2],fa[M],size[M],mx[M],mn[M],mc[M],cha[M],v[M];
    void up(int k)
    {
        int l=c[k][0],r=c[k][1];
        size[k]=size[l]+size[r]+1;
        mx[k]=mn[k]=v[k],mc[k]=cha[k];
        if(l)   mx[k]=max(mx[l],mx[k]),mn[k]=min(mn[k],mn[l]),mc[k]=min(mc[k],mc[l]);
        if(r)   mx[k]=max(mx[r],mx[k]),mn[k]=min(mn[k],mn[r]),mc[k]=min(mc[k],mc[r]);
    }
    void rotate(int x,int& k){
        int y=fa[x],z=fa[y],l=0,r=1;
        if(c[y][1]==x) l=1,r=0;
        if(y==k) k=x;
        else{if(c[z][0]==y) c[z][0]=x; else c[z][1]=x;}
        fa[y]=x; fa[x]=z; fa[c[x][r]]=y;
        c[y][l]=c[x][r]; c[x][r]=y;
        up(y); up(x);
    }
    void sp(int x,int& k){
        while(x!=k){
            int y=fa[x],z=fa[y];
            if(y!=k){
                if(c[z][0]==y^c[y][0]==x) rotate(y,k);
                else rotate(x,k);
            }
            rotate(x,k);
        }
    }
    int find(int x,int rank){
        if(!x) return 0;
        int l=c[x][0],r=c[x][1];
        if(size[l]+1==rank) return x;
        else if(size[l]>=rank) return find(l,rank);
        else find(r,rank-size[l]-1);
    }
    int build(int l,int r){
        if(l>r) return 0;
        int m=(l+r)>>1;
        c[m][0]=build(l,m-1);
        c[m][1]=build(m+1,r);
        for(int i=0;i<2;i++) if(c[m][i]) fa[c[m][i]]=m;
        up(m);
        return m;
    }
    int push_max(int l,int r){
        int x=find(root,l),y=find(root,r+2);
        sp(x,root); sp(y,c[x][1]);
        printf("%d
    ",mx[c[y][0]]-mn[c[y][0]]);
    }
    int push_min(int l,int r){
        int x=find(root,l+1),y=find(root,r+2);
        sp(x,root); sp(y,c[x][1]);
        printf("%d
    ",mc[c[y][0]]);
    }
    void insert(int k,int w){
        int x=find(root,k+1),y=find(root,k+2);
        sp(x,root); sp(y,c[x][1]);
        size[++sum]=1; mx[sum]=mn[sum]=v[sum]=w;  
        mc[sum]=cha[sum]=abs(v[sum]-v[x]); cha[y]=abs(v[y]-v[sum]);
        c[y][0]=sum; fa[sum]=y;
        up(y); up(x);
    }
    void merge(int k,int w){
        int x=find(root,k),y=find(root,k+3);
        sp(x,root); sp(y,c[x][1]);
        int p=c[y][0]; 
        c[p][0]=c[p][1]=0; mx[p]=mn[p]=v[p]=w;  
        mc[p]=cha[p]=abs(v[p]-v[x]); cha[y]=abs(v[y]-v[p]); size[p]=1;
        up(y); up(x);
    }
    int main()
    {
        n=read(); m=read(); v[2]=read();
        for(int i=3;i<=n+1;i++) v[i]=read(),cha[i]=abs(v[i]-v[i-1]);
        sum=n+2;
        root=build(1,n+2);
        char ch[10];
        int x,y;
        while(m--){
            scanf("%s",ch); x=read(); y=read();
            if(ch[1]=='e') merge(x,y);
            else if(ch[0]=='i') insert(x,y);
            else if(ch[1]=='a') push_max(x,y);
            else if(ch[1]=='i') push_min(x,y);
        }
        return 0;
    }
    
    View Code
  • 相关阅读:
    如何用C++操作无线网卡开启共享热点WiFi?
    delphi中的copy函数和pos函数
    C#使用WinAPI 修改电源设置,临时禁止笔记本合上盖子时睡眠(使用PowerGetActiveScheme等函数,以及C#对WINAPI的调用)
    发布Qt Widgets桌面应用程序的方法(自定义进程步骤,用QT Creator直接生成)
    认识TDD
    基于Bootstrap的Asp.net Mvc 分页
    Chrome控制台 JS调试
    英语学习
    JavaScript中的作用域和声明提前
    LeetCode: Distinct Subsequences
  • 原文地址:https://www.cnblogs.com/lyzuikeai/p/6932736.html
Copyright © 2011-2022 走看看