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 }