[HEOI 2016] sort

[HEOI 2016] sort

解题报告

码线段树快调废我了= =

其实这题貌似暴力分很足,直接$STL$的$SORT$就能$80$

正解:

我们可以二分答案来做这道题

假设我们二分的答案为$a$,我们就可以将整个序列分为两个集合,一个是大于等于$a$的,一个是小于$a$的

那么我们就可以将大于等于$a$的赋值为$1$,小于$a$的赋值为$0$,那么对于排序,我们就变成了线段树区间覆盖,升序就将区间中所有的$0$覆盖到前面,$1$覆盖到后面,反之亦然。

最后我们查询询问位置的数,是$1$说明二分的答案小了,需要左边界右移,反之则右边界左移。

  1 #include<iostream>
  2 #include<cstring>
  3 #include<cstdio>
  4 using namespace std;
  5 inline int read(){
  6     int sum(0);
  7     char ch(getchar());
  8     for(;ch<'0'||ch>'9';ch=getchar());
  9     for(;ch>='0'&&ch<='9';sum=sum*10+(ch^48),ch=getchar());
 10     return sum;
 11 }
 12 int n,m,q;
 13 int op[100005],l[100005],r[100005];
 14 int a[100005];
 15 int sum[400005],add[400005];
 16 inline void pushup(int i){
 17     sum[i]=sum[i<<1]+sum[i<<1|1];
 18 }
 19 inline void pushdown(int i,int len){
 20     if(add[i]!=-1){
 21         add[i<<1]=add[i];
 22         add[i<<1|1]=add[i];
 23         sum[i<<1]=add[i]*(len-(len>>1));
 24         sum[i<<1|1]=add[i]*(len>>1);
 25         add[i]=-1;
 26     }
 27 }
 28 inline void build(int l,int r,int i,int x){
 29     add[i]=-1;
 30     if(l==r){
 31         if(a[l]>=x)
 32             sum[i]=1;
 33         else
 34             sum[i]=0;
 35         return;
 36     }
 37     int mid((l+r)>>1);
 38     build(l,mid,i<<1,x);
 39     build(mid+1,r,i<<1|1,x);
 40     pushup(i);
 41 }
 42 inline void update(int ll,int rr,int l,int r,int w,int i){//cout<<"update"<<ll<<' '<<rr<<' '<<l<<' '<<r<<' '<<w<<' '<<i<<endl;
 43     if(ll>rr)
 44         return;
 45     if(ll<=l&&r<=rr){
 46         sum[i]=w*(r-l+1);
 47         add[i]=w;
 48         return;
 49     }
 50     pushdown(i,r-l+1);
 51     int mid((l+r)>>1);
 52     if(ll<=mid)
 53         update(ll,rr,l,mid,w,i<<1);
 54     if(mid<rr)
 55         update(ll,rr,mid+1,r,w,i<<1|1);
 56     pushup(i);
 57 }
 58 inline int query(int ll,int rr,int l,int r,int i){
 59     if(ll<=l&&r<=rr)
 60         return sum[i];
 61     pushdown(i,r-l+1);
 62     int mid((l+r)>>1),ret(0);
 63     if(ll<=mid)
 64         ret+=query(ll,rr,l,mid,i<<1);
 65     if(mid<rr)
 66         ret+=query(ll,rr,mid+1,r,i<<1|1);
 67     return ret;
 68 }
 69 inline bool check(int x){
 70     build(1,n,1,x);
 71     for(int i=1;i<=m;++i){//cout<<l[i]<<' '<<r[i]<<endl;
 72         int tmp(query(l[i],r[i],1,n,1));//cout<<i<<' '<<op[i]<<' '<<l[i]<<' '<<r[i]<<endl;
 73         if(op[i]==0){//cout<<r[i]-tmp+1<<' '<<r[i]<<"devide"<<l[i]<<' '<<r[i]-tmp<<endl;
 74             update(l[i],r[i]-tmp,1,n,0,1);
 75             if(tmp!=0)
 76                 update(r[i]-tmp+1,r[i],1,n,1,1);
 77         }
 78         else{//cout<<l[i]<<' '<<l[i]+tmp-1<<"devide"<<l[i]+tmp<<' '<<r[i]<<endl;
 79             update(l[i],l[i]+tmp-1,1,n,1,1);
 80             if(tmp!=r[i]-l[i]+1)
 81                 update(l[i]+tmp,r[i],1,n,0,1);
 82         }
 83     }
 84     return query(q,q,1,n,1);
 85 }
 86 inline void ef(int l,int r){
 87     while(l+1<r){
 88         int mid((l+r)>>1);
 89         if(check(mid))
 90             l=mid;
 91         else
 92             r=mid;
 93     }
 94     printf("%d",l);
 95 }
 96 inline int gg(){
 97     freopen("heoi2016_sort.in","r",stdin);
 98     freopen("heoi2016_sort.out","w",stdout);
 99     n=read(),m=read();
100     for(int i=1;i<=n;++i)
101         a[i]=read();
102     for(int i=1;i<=m;++i)
103         op[i]=read(),l[i]=read(),r[i]=read();
104     q=read();
105     ef(1,n);
106 //    printf("%d",ans);
107     return 0;
108 }
109 int K(gg());
110 int main(){;}
View Code
原文地址:https://www.cnblogs.com/hzoi-mafia/p/7358489.html