zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    linux学习笔记 ftp命令
    linux 学习笔记 wc命令
    linux 学习笔记 finding people
    通配符
    linux 学习笔记 管道 pipe ls cp mv
    linux学习笔记 其他常用命令
    linux 学习笔记 执行脚本篇章
    solr分词一:mmseg4j
    solr介绍一:Analyzer(分析器)、Tokenizer(分词器)
    solr-4.10.2版本使用tomcat7部署
  • 原文地址:https://www.cnblogs.com/yzxverygood/p/9751008.html
Copyright © 2011-2022 走看看