zoukankan      html  css  js  c++  java
  • 【BZOJ4552】【TJOI2016】【HEOI2016】排序

    经验还是不够……

    原题:

    在2016年,佳媛姐姐喜欢上了数字序列。因而他经常研究关于序列的一些奇奇怪怪的问题,现在他在研究一个难题
    ,需要你来帮助他。这个难题是这样子的:给出一个1到n的全排列,现在对这个全排列序列进行m次局部排序,排
    序分为两种:1:(0,l,r)表示将区间[l,r]的数字升序排序2:(1,l,r)表示将区间[l,r]的数字降序排序最后询问第q
    位置上的数字。
    1 <= n, m <= 10^5
     
    没思路,看题解
    这个本应不看题解的,但是急于刷AC数就看了,果然还是要放下每日6题的任务?
    正解是二分一个值,把序列中<=它的设为1,大于的设为0,然后建线段树
    每次排序先查询区间中有多少个1,然后以1的个数为分界线,根据升序或降序把左边和右边分别buff成1或0
    这样一番操作之后第x的位置的值就表示位置x上的数和当前二分的数的大小关系
    然后根据这个二分就行了
    暂时不能把这个方法延伸到更多的地方去,需要再思考
    代码:
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cmath>
     6 using namespace std;
     7 const int oo=168430090;
     8 int rd(){int z=0,mk=1;  char ch=getchar();
     9     while(ch<'0'||ch>'9'){if(ch=='-')mk=-1;  ch=getchar();}
    10     while(ch>='0'&&ch<='9'){z=(z<<3)+(z<<1)+ch-'0';  ch=getchar();}
    11     return z*mk;
    12 }
    13 struct dcd{int mk,x,y;}b[110000];
    14 int n,m,a[110000],qst;
    15 int v[410000],dt[410000];
    16 int mn=oo,mx=0;
    17 void gtsgmttr(int x,int y,int l,int r){
    18     dt[x]=-1,v[x]=0;
    19     if(l==r){  v[x]=(y>=a[l]);  return ;}
    20     int md=(l+r)>>1;
    21     gtsgmttr(x<<1,y,l,md),gtsgmttr(x<<1|1,y,md+1,r);
    22     v[x]=v[x<<1]+v[x<<1|1];
    23 }
    24 void pshd(int x,int l,int r,int md){
    25     if(dt[x]==-1)  return ;
    26     v[x<<1]=(md-l+1)*dt[x],v[x<<1|1]=(r-md)*dt[x];
    27     dt[x<<1]=dt[x<<1|1]=dt[x];
    28     dt[x]=-1;
    29 }
    30 void mdf(int x,int l,int r,int z,int ll,int rr){
    31     if(l>r)  return ;
    32     if(l==ll && r==rr){  v[x]=(r-l+1)*z,dt[x]=z;  return ;}
    33     int md=(ll+rr)>>1;  pshd(x,ll,rr,md);
    34     if(l<=md && r>md)  mdf(x<<1,l,md,z,ll,md),mdf(x<<1|1,md+1,r,z,md+1,rr);
    35     else if(r<=md)  mdf(x<<1,l,r,z,ll,md);
    36     else  mdf(x<<1|1,l,r,z,md+1,rr);
    37     v[x]=v[x<<1]+v[x<<1|1];
    38 }
    39 int qr(int x,int l,int r,int ll,int rr){
    40     if(l==ll && r==rr)  return v[x];
    41     int md=(ll+rr)>>1;  pshd(x,ll,rr,md);
    42     if(l<=md && r>md)  return qr(x<<1,l,md,ll,md)+qr(x<<1|1,md+1,r,md+1,rr);
    43     else if(r<=md)  return qr(x<<1,l,r,ll,md);
    44     else  return qr(x<<1|1,l,r,md+1,rr);
    45 }
    46 int sch(int x,int y,int ll,int rr){
    47     if(y==ll && y==rr)  return v[x];
    48     int md=(ll+rr)>>1;  pshd(x,ll,rr,md);
    49     if(y<=md)  return sch(x<<1,y,ll,md);
    50     else  return sch(x<<1|1,y,md+1,rr);
    51 }
    52 bool chck(int x){
    53     gtsgmttr(1,x,1,n);
    54     //cout<<x<<endl;
    55     //for(int i=1;i<=n;++i)  printf("%d ",sch(1,i,1,n));
    56     //cout<<endl;
    57     int bwl;
    58     for(int i=1;i<=m;++i){
    59         bwl=qr(1,b[i].x,b[i].y,1,n);
    60         /*if(b[i].mk)  mdf(1,b[i].x,b[i].x+bwl-1,0,1,n),mdf(1,b[i].x+bwl,b[i].y,1,1,n);
    61         else  mdf(1,b[i].x,b[i].y-bwl,1,1,n),mdf(1,b[i].y-bwl+1,b[i].y,0,1,n);*/
    62         if(b[i].mk)  mdf(1,b[i].x,b[i].y-bwl,0,1,n),mdf(1,b[i].y-bwl+1,b[i].y,1,1,n);
    63         else  mdf(1,b[i].x,b[i].x+bwl-1,1,1,n),mdf(1,b[i].x+bwl,b[i].y,0,1,n);
    64         //for(int j=1;j<=n;++j)  printf("%d ",sch(1,j,1,n));
    65         //cout<<endl;
    66     }
    67     return sch(1,qst,1,n);
    68 }
    69 int bnrsch(){
    70     int l=mn,r=mx,md;
    71     while(l+1<r)  md=(l+r)>>1,(chck(md) ? r : l)=md;
    72     return chck(l) ? l : r;
    73 }
    74 int main(){//freopen("ddd.in","r",stdin);
    75     cin>>n>>m;
    76     for(int i=1;i<=n;++i)  a[i]=rd(),mn=min(mn,a[i]),mx=max(mx,a[i]);
    77     for(int i=1;i<=m;++i)  b[i].mk=rd(),b[i].x=rd(),b[i].y=rd();
    78     cin>>qst;
    79     cout<<bnrsch()<<endl;
    80     return 0;
    81 }
    View Code
  • 相关阅读:
    Python-手动安装第三方包
    SQL SERVER-根据jobID查job
    python-包模块等概念
    锁表
    Python-try异常捕获
    胶水语言
    C++之多态性与虚函数
    android
    开源许可协议
    hal
  • 原文地址:https://www.cnblogs.com/JSL2018/p/6558306.html
Copyright © 2011-2022 走看看