今天考试的T3题目 好像也不是很难 但是蒟蒻的我就是想不到啊哎
我也不知道出题人怎么想到的
考虑二分答案 设当前二分的答案为
mid
m
i
d
则把序列中大于等于
mid
m
i
d
的位置设为
1
1
, 其他位置设为,放到一颗线段树上,那么
1
1
操作是让大的值在两边, 那么就可以转化为两端区间赋值为,中间区间赋值为
0
0
,最后如果询问的位置的答案为
1
1
表示当前答案可行,2操作看了题解也看不懂,感觉自己陷入了一点思维误区,总想着把这个东西可持久化..实际上用一个栈把这些操作存下来,如果遇到一个操作你就把前面的都删除就好了, 这样总的复杂度是两个
log
l
o
g
的, 就可以通过此题啦.
链接
Codes
#include<bits/stdc++.h>
#define For(i, a, b) for(register int i = a; i <= b; ++ i)
using namespace std;
const int maxn = 5e5 + 10;
int n, m, q, cnt, a[maxn];
struct Query {
int opt, x, y;
}Q[maxn];
struct Segment_Tree {
#define mid ((l + r) >> 1)
#define ls (bh << 1)
#define rs (ls | 1)
int s[maxn << 2], lazy[maxn << 2];
void pushup(int bh) {
s[bh] = s[ls] + s[rs];
}
void pushdown(int bh, int l, int r) {
if(lazy[bh] != -1) {
lazy[ls] = lazy[rs] = lazy[bh];
s[ls] = lazy[bh] * (mid - l + 1);
s[rs] = lazy[bh] * (r - mid);
lazy[bh] = -1;
}
}
void build(int bh, int l, int r, int p) {
lazy[bh] = -1;
if(l == r)
s[bh] = (a[l] >= p);
else {
build(ls, l, mid, p);
build(rs, mid + 1, r, p);
pushup(bh);
}
}
void update(int bh, int l, int r, int x, int y, int z) {
if(x <= l && r <= y) {
s[bh] = (r - l + 1) * z;
lazy[bh] = z;
}
else {
pushdown(bh, l, r);
if(x <= mid) update(ls, l, mid, x, y, z);
if(y > mid) update(rs, mid + 1, r, x, y, z);
pushup(bh);
}
}
int query(int bh, int l, int r, int x, int y) {
int res = 0;
if(x <= l && r <= y)
res += s[bh];
else {
pushdown(bh, l, r);
if(x <= mid) res += query(ls, l, mid, x, y);
if(y > mid) res += query(rs, mid + 1, r, x, y);
}
return res;
}
}T;
void File() {
freopen("coach.in", "r", stdin);
freopen("coach.out", "w", stdout);
}
void Init() {
int x, y, z;
scanf("%d%d%d", &n, &m, &q);
For(i, 1, n)
scanf("%d", &a[i]);
For(i, 1, m) {
scanf("%d%d", &x, &y);
if(x == 1) {
scanf("%d", &z);
Q[++ cnt] = (Query){x, y, z};
}
else cnt = max(0, cnt - y);
}
}
void Solve() {
int ans, l = 1, r = 2e5;
int L1, L2, R1, R2, sum;
while(l <= r) {
T.build(1, 1, n, mid);
For(i, 1, cnt) {
sum = T.query(1, 1, n, Q[i].x, Q[i].y);
if(sum == 0 || sum == (Q[i].y - Q[i].x + 1))
continue;
L1 = Q[i].x, R1 = Q[i].x + sum / 2 + sum % 2 - 1;
L2 = Q[i].y - sum / 2 + 1, R2 = Q[i].y;
T.update(1, 1, n, L1, R1, 1);
T.update(1, 1, n, L2, R2, 1);
if(R1 + 1 <= L2 - 1)
T.update(1, 1, n, R1 + 1, L2 - 1, 0);
}
if(T.query(1, 1, n, q, q) == 1)
ans = mid, l = mid + 1;
else r = mid - 1;
}
printf("%d\n", ans);
}
int main() {
File();
Init();
Solve();
return 0;
}