bzoj4552[Tjoi2016&Heoi2016]排序

bzoj4552[Tjoi2016&Heoi2016]排序

题意:

给出一个1到n的全排列,现在对这个全排列序列进行m次局部排序,排序分为两种:1:(0,l,r)表示将区间[l,r]的数字升序排序2:(1,l,r)表示将区间[l,r]的数字降序排序,最后询问第q位置上的数字。

题解:

二分最后这个数,判定一个数就是令数组中>它为1,≤它的为0。然后把排序转成线段树区间赋值,最后查询q位置的数。如果为1则用来判定的数<答案,如果为0则用来判定的数≥答案。反思:查询区间里有多少个1后,区间赋值时如果查询结果为0,那么区间赋值左端点=r-0+1,右端点=r,则会导致左端点大于右端点,那么就会wa,当查询结果等于区间长度时也会发生类似情况。

代码:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #define maxn 100010
 5 #define inc(i,j,k) for(int i=j;i<=k;i++)
 6 using namespace std;
 7 
 8 inline int read(){
 9     char ch=getchar(); int f=1,x=0;
10     while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();} while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
11     return f*x;
12 }
13 int n,m,v[maxn],opt[maxn],x[maxn],y[maxn],l,r,k,sm[maxn*5],tag[maxn*5],ll[maxn*5],rr[maxn*5]; bool bit[maxn];
14 void update(int x){sm[x]=sm[x<<1]+sm[x<<1|1];}
15 void pushdown(int x){
16     if(tag[x]!=-1&&ll[x]!=rr[x]){
17         sm[x<<1]=tag[x]*(rr[x<<1]-ll[x<<1]+1); tag[x<<1]=tag[x];
18         sm[x<<1|1]=tag[x]*(rr[x<<1|1]-ll[x<<1|1]+1); tag[x<<1|1]=tag[x];
19         tag[x]=-1;
20     }
21 }
22 void build(int x,int l,int r){
23     tag[x]=-1; ll[x]=l; rr[x]=r; if(l==r){sm[x]=bit[l]; return;} int mid=(l+r)>>1;
24     build(x<<1,l,mid); build(x<<1|1,mid+1,r); update(x);
25 }
26 void modify(int x,int ql,int qr,bool bit){
27     if(ql>qr)return; pushdown(x);
28     if(ql<=ll[x]&&rr[x]<=qr){tag[x]=bit; sm[x]=bit*(rr[x]-ll[x]+1); return;} int mid=(ll[x]+rr[x])>>1;
29     if(ql<=mid)modify(x<<1,ql,qr,bit); if(mid<qr)modify(x<<1|1,ql,qr,bit); update(x);
30 }
31 int query(int x,int ql,int qr){
32     pushdown(x);
33     if(ql<=ll[x]&&rr[x]<=qr){return sm[x];} int mid=(ll[x]+rr[x])>>1,q=0;
34     if(ql<=mid)q+=query(x<<1,ql,qr); if(mid<qr)q+=query(x<<1|1,ql,qr); return q;
35 }
36 bool check(int o){
37     inc(i,1,n)bit[i]=(v[i]>o); build(1,1,n);
38     inc(i,1,m){
39         int q=query(1,x[i],y[i]);
40         if(!opt[i])modify(1,x[i],y[i]-q,0),modify(1,y[i]-q+1,y[i],1);
41         else modify(1,x[i],x[i]+q-1,1),modify(1,x[i]+q,y[i],0);
42     }
43     if(query(1,k,k))return 1;else return 0;
44 }
45 int main(){
46     n=read(); m=read(); inc(i,1,n)v[i]=read(); inc(i,1,m)opt[i]=read(),x[i]=read(),y[i]=read();
47     k=read(); l=1; r=n;
48     while(l<r){
49         int mid=(l+r)>>1; if(check(mid))l=mid+1;else r=mid;
50     }
51     printf("%d",l);
52 }

20160630

原文地址:https://www.cnblogs.com/YuanZiming/p/5720794.html