HEOI2016/TJOI2016 排序
Posted morslin
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HEOI2016/TJOI2016 排序相关的知识,希望对你有一定的参考价值。
奇妙的题目
把操作离线下来,二分第(q)位置上的数(x),将排列中大于(x)的数记为(1),小于(x)的数记为(0),然后就可以很简单的用线段树维护每个操作
最后判断(q)位置上的数是否为(1)
时间复杂度(O(nlog^2 n))
#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
#define LL long long
#define ls p << 1
#define rs p << 1 | 1
#define mid ((l+r) >> 1)
using namespace std;
LL read() {
LL k = 0, f = 1; char c = getchar();
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9')
k = k * 10 + c - 48, c = getchar();
return k * f;
}
struct zzz {
int num1, num0;
}tree[100010 << 2];
struct hhh {
bool opt; int l, r;
}que[100010];
int tag[100010 << 2];
int n, q, pos, a[100010], b[100010];
inline void up(int p) {
tree[p].num0 = tree[ls].num0 + tree[rs].num0;
tree[p].num1 = tree[ls].num1 + tree[rs].num1;
}
inline void down(int p) {
if(tag[p] != -1) {
if(!tag[p]) {
tree[ls].num0 = tree[ls].num0 + tree[ls].num1;
tree[ls].num1 = 0;
tree[rs].num0 = tree[rs].num0 + tree[rs].num1;
tree[rs].num1 = 0;
tag[ls] = tag[rs] = tag[p]; tag[p] = -1;
}
else {
tree[ls].num1 = tree[ls].num0 + tree[ls].num1;
tree[ls].num0 = 0;
tree[rs].num1 = tree[rs].num0 + tree[rs].num1;
tree[rs].num0 = 0;
tag[ls] = tag[rs] = tag[p]; tag[p] = -1;
}
}
}
void build(int l = 1, int r = n, int p = 1) {
tag[p] = -1; tree[p].num0 = tree[p].num1 = 0;
if(l == r) {
if(a[l]) tree[p].num1 = 1;
else tree[p].num0 = 1;
return ;
}
build(l, mid, ls); build(mid+1, r, rs);
up(p);
}
int query(int nl, int nr, int l = 1, int r = n, int p = 1) {
if(nl <= l && nr >= r) return tree[p].num0;
down(p);
int ans = 0;
if(nl <= mid) ans += query(nl, nr, l, mid, ls);
if(nr > mid) ans += query(nl, nr, mid+1, r, rs);
return ans;
}
void update(int nl, int nr, bool k, int l = 1, int r = n, int p = 1) {
if(nl <= l && nr >= r) {
if(!k) {
tree[p].num0 = tree[p].num0 + tree[p].num1;
tree[p].num1 = 0; tag[p] = k;
}
else {
tree[p].num1 = tree[p].num0 + tree[p].num1;
tree[p].num0 = 0; tag[p] = k;
}
return ;
}
down(p);
if(nl <= mid) update(nl, nr, k, l, mid, ls);
if(nr > mid) update(nl, nr, k, mid+1, r, rs);
up(p);
}
bool check(int k) {
build();
for(int i = 1; i <= q; ++i) {
int cnt = query(que[i].l, que[i].r);
//注意区间全部为1和全部为0的情况
if(cnt == 0) {
update(que[i].l, que[i].r, 1); continue;
}
if(cnt == que[i].r-que[i].l+1) {
update(que[i].l, que[i].r, 0); continue;
}
if(que[i].opt)
update(que[i].l, que[i].r-cnt, 1),
update(que[i].r-cnt+1, que[i].r, 0);
else
update(que[i].l, que[i].l+cnt-1, 0),
update(que[i].l+cnt, que[i].r, 1);
}
return !query(pos, pos);
}
int main() {
n = read(), q = read();
for(int i = 1; i <= n; ++i) b[i] = read();
for(int i = 1; i <= q; ++i)
que[i].opt = read(), que[i].l = read(), que[i].r = read();
pos = read();
int l = 1, r = n, ans = 0;
while(l <= r) {
for(int i = 1; i <= n; ++i)
if(b[i] >= mid) a[i] = 1;
else a[i] = 0;
if(check(mid)) ans = mid, l = mid+1;
else r = mid - 1;
}
cout << ans;
return 0;
}
以上是关于HEOI2016/TJOI2016 排序的主要内容,如果未能解决你的问题,请参考以下文章