[bzoj4552]排序

考虑二分枚举答案,变成01的一个序列,用线段树来维护排序即可

 1 #include
 2 using namespace std;
 3 #define N 100005
 4 #define L (k<<1)
 5 #define R (L+1)
 6 #define mid (l+r>>1)
 7 struct ji{
 8     int p,x,y;
 9 }v[N];
10 int n,m,p,x,y,a[N],f[N<<2],laz[N<<2];
11 void upd(int k,int l,int r,int x){
12     laz[k]=x;
13     f[k]=(r-l+1)*x;
14 }
15 void down(int k,int l,int r){
16     if (laz[k]==-1)return;
17     upd(L,l,mid,laz[k]);
18     upd(R,mid+1,r,laz[k]);
19     laz[k]=-1;
20 }
21 void update(int k,int l,int r,int x,int y,int z){
22     if ((l>y)||(x>r))return;
23     if ((x<=l)&&(r<=y)){
24         upd(k,l,r,z);
25         return;
26     }
27     down(k,l,r);
28     update(L,l,mid,x,y,z);
29     update(R,mid+1,r,x,y,z);
30     f[k]=f[L]+f[R];
31     if (laz[k]!=-1)upd(k,l,r,laz[k]);
32 }
33 int query(int k,int l,int r,int x,int y){
34     if ((l>y)||(x>r))return 0;
35     if ((x<=l)&&(r<=y))return f[k];
36     down(k,l,r);
37     return query(L,l,mid,x,y)+query(R,mid+1,r,x,y);
38 }
39 bool pd(int k){
40     memset(laz,-1,sizeof(laz));
41     update(1,1,n,1,n,0);
42     for(int i=1;i<=n;i++)
43         if (a[i]>=k)update(1,1,n,i,i,1);
44         else update(1,1,n,i,i,0);
45     for(int i=1;i<=m;i++){
46         int x=query(1,1,n,v[i].x,v[i].y);
47         if (!v[i].p){
48             update(1,1,n,v[i].x,v[i].y-x,0);
49             update(1,1,n,v[i].y-x+1,v[i].y,1);
50         }
51         else{
52             update(1,1,n,v[i].x,v[i].x+x-1,1);
53             update(1,1,n,v[i].x+x,v[i].y,0);
54         }
55     }
56     return query(1,1,n,p,p);
57 }
58 int main(){
59     scanf("%d%d",&n,&m);
60     for(int i=1;i<=n;i++)scanf("%d",&a[i]);
61     for(int i=1;i<=m;i++){
62         scanf("%d%d%d",&p,&x,&y);
63         v[i]=ji{p,x,y};
64     }
65     scanf("%d",&p);
66     x=1,y=n;
67     while (x<y){
68         int m=(x+y+1>>1);
69         if (pd(m))x=m;
70         else y=m-1;
71     }
72     printf("%d",x);
73 }
View Code

 

你可能感兴趣的:([bzoj4552]排序)