1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
| #include <cstdio>
using namespace std;
const int MAXN = 31000;
namespace SegTree{
#define lson (nown<<1)
#define rson (nown<<1|1)
#define mid ((l+r)>>1)
int sumn[MAXN<<2],lazy[MAXN<<2];// -1 -> no label
void add_label(int nown,int l,int r,int op){
lazy[nown] = op,sumn[nown] = (r-l+1)*op;
}
void push_down(int nown,int l,int r){
if(lazy[nown] != -1){
add_label(lson,l,mid,lazy[nown]);
add_label(rson,mid+1,r,lazy[nown]);
lazy[nown] = -1;
}
}
void push_up(int nown){
sumn[nown] = sumn[lson] + sumn[rson];
}
void build(int nown,int l,int r,int k,int *a){
lazy[nown] = -1;
if(l == r){
sumn[nown] = k < a[l];// 满足条件(<=)的 sumn 为 0
}
else{
build(lson,l,mid,k,a),build(rson,mid+1,r,k,a);
push_up(nown);
}
}
int query(int nown,int l,int r,int ql,int qr){
if(ql <= l && r <= qr){
return sumn[nown];
}
else{
push_down(nown,l,r);
int ans = 0;
if(ql <= mid)
ans += query(lson,l,mid,ql,qr);
if(qr >= mid+1)
ans += query(rson,mid+1,r,ql,qr);
return ans;
}
}
void update(int nown,int l,int r,int ql,int qr,int op){
if(ql <= l && r <= qr){
add_label(nown,l,r,op);
}
else{
push_down(nown,l,r);
if(ql <= mid)
update(lson,l,mid,ql,qr,op);
if(qr >= mid+1)
update(rson,mid+1,r,ql,qr,op);
push_up(nown);
}
}
void print(int nown,int l,int r){
printf("nown:%d l,r:%d %d sumn:%d lazy:%d\n",nown,l,r,sumn[nown],lazy[nown]);
if(l == r) return;
print(lson,l,mid);
print(rson,mid+1,r);
}
void sort(int n,int l,int r,int op){// op 为 0 正序 , op 为 1 逆序
int b = query(1,1,n,l,r),a = (r-l+1) - b;
//printf("a:%d b:%d\n",a,b);
if(op == 0){
if(a) update(1,1,n,l,l+a-1,0);
if(b) update(1,1,n,r-b+1,r,1);
}
else{
if(b) update(1,1,n,l,l+b-1,1);
if(a) update(1,1,n,r-a+1,r,0);
}
}
#undef lson
#undef rson
#undef mid
}
int n,m,q;
int a[MAXN];
int o[MAXN],l[MAXN],r[MAXN];
void init(){
scanf("%d %d",&n,&m);
for(int i = 1;i<=n;i++)
scanf("%d",&a[i]);
for(int i = 1;i<=m;i++)
scanf("%d %d %d",&o[i],&l[i],&r[i]);
scanf("%d",&q);
}
bool check(int k){//检查 q 位置上的数是不是小于等于 k
SegTree::build(1,1,n,k,a);
for(int i = 1;i<=m;i++)
SegTree::sort(n,l[i],r[i],o[i]);
return SegTree::query(1,1,n,q,q) == 0;
}
void solve(){
int b = 1,e = n;
while(b!=e){
int mid = (b+e)>>1;
//printf("%d %d:%d\n",b,e,mid);
if(check(mid))
e = mid;
else
b = mid+1;
}
printf("%d\n",b);
}
int main(){
init();
solve();
return 0;
}
|