BZOJ4552: [Tjoi2016&Heoi2016]排序

n<=1e5个数字,做m<=1e5次操作:把第Li到Ri的数字升序/降序排,求最后第Q位的数字。

似乎没有什么数据结构可以做这个?但可以转判定性问题。就是说,把一段数排序是没法的,但把一个01串排序是可以线段树乱搞的。

所以二分一个答案,比它小(等)的数都记0,比它大的都记1,如果最后第Q位0就没毛病试下更小的数,如果是1就得调大。

线段树记区间1的个数即可。

  1 #include<stdio.h>
  2 #include<string.h>
  3 #include<stdlib.h>
  4 #include<algorithm>
  5 //#include<iostream>
  6 using namespace std;
  7 
  8 int n,m,q;
  9 #define maxn 200011
 10 int a[maxn];bool now[maxn];
 11 struct SMT
 12 {
 13     struct Node
 14     {
 15         int num;
 16         int be;
 17         int l,r;
 18         int ls,rs;
 19     }a[maxn<<1];
 20     int size;
 21     void up(int x)
 22     {
 23         const int &p=a[x].ls,&q=a[x].rs;
 24         a[x].num=a[p].num+a[q].num;
 25     }
 26     void besingle(int x,bool v)
 27     {
 28         a[x].be=v;
 29         a[x].num=v?a[x].r-a[x].l+1:0;
 30     }
 31     void down(int x)
 32     {
 33         if (!x) return;
 34         const int &p=a[x].ls,&q=a[x].rs;
 35         if (a[x].be!=-1)
 36         {
 37             besingle(p,a[x].be);
 38             besingle(q,a[x].be);
 39             a[x].be=-1;
 40         }
 41     }
 42     void build(int &x,int L,int R)
 43     {
 44         x=++size;
 45         a[x].l=L;a[x].r=R;
 46         a[x].be=-1;
 47         if (L==R) {a[x].num=now[L];a[x].ls=a[x].rs=0;return;}
 48         const int mid=(L+R)>>1;
 49         build(a[x].ls,L,mid);
 50         build(a[x].rs,mid+1,R);
 51         up(x);
 52     }
 53     void build()
 54     {
 55         size=0;
 56         int x;build(x,1,n);
 57     }
 58     int ql,qr,v;
 59     void Be(int x)
 60     {
 61         if (ql<=a[x].l && a[x].r<=qr) {besingle(x,v);return;}
 62         down(x);
 63         const int mid=(a[x].l+a[x].r)>>1;
 64         if (ql<=mid) Be(a[x].ls);
 65         if (qr> mid) Be(a[x].rs);
 66         up(x);
 67     }
 68     void Be(int L,int R,bool v)
 69     {
 70         ql=L;qr=R;this->v=v;
 71         Be(1);
 72     }
 73     int query(int x)
 74     {
 75         if (ql<=a[x].l && a[x].r<=qr) return a[x].num;
 76         down(x);
 77         const int mid=(a[x].l+a[x].r)>>1;
 78         int ans=0;
 79         if (ql<=mid) ans+=query(a[x].ls);
 80         if (qr> mid) ans+=query(a[x].rs);
 81         return ans;
 82     }
 83     int query(int L,int R)
 84     {
 85         ql=L;qr=R;
 86         return query(1);
 87     }
 88 }t;
 89 struct DOO
 90 {
 91     int ty,l,r;
 92 }doo[maxn];
 93 void play(int i)
 94 {
 95     int tmp=t.query(doo[i].l,doo[i].r);
 96     if (doo[i].ty)
 97     {
 98         t.Be(doo[i].l,doo[i].l+tmp-1,1);
 99         t.Be(doo[i].l+tmp,doo[i].r,0);
100     }
101     else
102     {
103         t.Be(doo[i].r-tmp+1,doo[i].r,1);
104         t.Be(doo[i].l,doo[i].r-tmp,0);
105     }
106 }
107 bool check(int x)
108 {
109     for (int i=1;i<=n;i++) now[i]=(a[i]>x);
110     t.build();
111     for (int i=1;i<=m;i++)
112     {
113         play(i);
114     }
115     return !t.query(q,q);
116 }
117 int main()
118 {
119     scanf("%d%d",&n,&m);
120     for (int i=1;i<=n;i++) scanf("%d",&a[i]);
121     for (int i=1;i<=m;i++) scanf("%d%d%d",&doo[i].ty,&doo[i].l,&doo[i].r);
122     scanf("%d",&q);
123     int L=1,R=n+1;
124     while (L<R)
125     {
126         const int mid=(L+R)>>1;
127         if (check(mid)) R=mid;
128         else L=mid+1;
129     }
130     printf("%d\n",L);
131     return 0;
132 }
View Code

 

posted @ 2017-10-07 21:50  Blue233333  阅读(179)  评论(0编辑  收藏  举报