• p2824 [HEOI2016/TJOI2016]排序


    传送门

    分析

    二分一个数表示查询位置的数是多少,将序列中大于等于这个数的数赋为1,其余赋为0,对于每一个区间查询区间和(即区间内1的个数),然后区间修改将前/后半部分修改为1,其余修改为0即可

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<cctype>
    #include<cmath>
    #include<cstdlib>
    #include<ctime>
    #include<queue>
    #include<vector>
    #include<set>
    #include<map>
    #include<stack>
    using namespace std;
    int a[100100],d[400400],col[400400],k[100100],x[100100],y[100100];
    inline void update(int le,int ri,int wh,int pl,int sum){
          col[wh]=-1;
          if(le==ri){
              d[wh]=sum;
              return;
          }
          int mid=(le+ri)>>1;
          if(mid>=pl)update(le,mid,wh<<1,pl,sum);
            else update(mid+1,ri,wh<<1|1,pl,sum);
          d[wh]=d[wh<<1]+d[wh<<1|1];
          return;
    }
    inline void build(int le,int ri,int wh,int X,int Y,int sum){
          if(le>=X&&ri<=Y){
              col[wh]=sum;
              d[wh]=(ri-le+1)*sum;
              return;
          }
          int mid=(le+ri)>>1;
          if(col[wh]!=-1){
              col[wh<<1]=col[wh<<1|1]=col[wh];
              d[wh<<1]=col[wh]*(mid-le+1);
              d[wh<<1|1]=col[wh]*(ri-mid);
              col[wh]=-1;
          }
          if(mid>=X)build(le,mid,wh<<1,X,Y,sum);
          if(mid<Y)build(mid+1,ri,wh<<1|1,X,Y,sum);
          d[wh]=d[wh<<1]+d[wh<<1|1];
          return;
    }
    inline int q(int le,int ri,int wh,int X,int Y){
          if(le>=X&&ri<=Y)return d[wh];
          int mid=(le+ri)>>1,ans=0;
          if(col[wh]!=-1){
              col[wh<<1]=col[wh<<1|1]=col[wh];
              d[wh<<1]=col[wh]*(mid-le+1);
              d[wh<<1|1]=col[wh]*(ri-mid);
              col[wh]=-1;
          }
          if(mid>=X)ans+=q(le,mid,wh<<1,X,Y);
          if(mid<Y)ans+=q(mid+1,ri,wh<<1|1,X,Y);
          d[wh]=d[wh<<1]+d[wh<<1|1];
          return ans;
    }
    int main(){
          int n,m,i,j,l,r,pos;
          scanf("%d%d",&n,&m);
          for(i=1;i<=n;i++)scanf("%d",&a[i]);
          for(i=1;i<=m;i++)scanf("%d%d%d",&k[i],&x[i],&y[i]);
          scanf("%d",&pos);
          l=1,r=n+1;
          while(r-l>1){
              int mid=(l+r)>>1;
              for(i=1;i<=n;i++)
                update(1,n,1,i,(a[i]>=mid));
              for(i=1;i<=m;i++){
                int sum=q(1,n,1,x[i],y[i]);
                if(k[i]){
                    build(1,n,1,x[i],x[i]+sum-1,1);
                    build(1,n,1,x[i]+sum,y[i],0);
              }else {
                  build(1,n,1,x[i],y[i]-sum,0);
                    build(1,n,1,y[i]-sum+1,y[i],1);
              }
            }
            if(q(1,n,1,pos,pos))l=mid;
              else r=mid;
          }
          printf("%d
    ",l);
          return 0;
    }
  • 相关阅读:
    spring: web学习笔记1异常处理:No adapter for handler
    maven: maven编译时指定maven库,即指定profile
    spring: 一些基本配置也许只有自己能够读懂
    ruby: rdoc生成文档的好工具
    php: eclipse 编辑 php
    ssh免密码登录, 发送命令到多个Linux
    ruby: 使用netbeans debug ruby
    maven: maven创建工程,web工程等普通java app, web app
    IE, firefox竖向 横向滚动条处理
    获取指定进程在一段时间内cpu和内存的最大最小值【调试版】
  • 原文地址:https://www.cnblogs.com/yzxverygood/p/9751008.html
Copyright © 2020-2023  润新知