Files
python/TangDou/AcWing/SegmentTree/P3567.cpp
HuangHai 1f397eca87 'commit'
2025-08-30 18:35:01 +08:00

76 lines
2.7 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 5e5 + 10;
const int M = N * 32;
struct Node {
int l, r, cnt; //[l,r]管辖范围,cnt:区间中元素个数和
} tr[M];
int n, m;
int root[N], idx;
int read() {
int x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-') f = -1;
ch = getchar();
}
while ('0' <= ch && ch <= '9') {
x = (x << 3) + (x << 1) + (ch ^ 48);
ch = getchar();
}
return x * f;
}
//经典的主席树插入
void insert(int &u, int l, int r, int x) {
tr[++idx] = tr[u]; //新开一个节点idx++,将新节点指向旧的tr[u]
u = idx; //因为是引用,为了回传正确值,需要u=idx-1
tr[u].cnt++; //新节点的cnt,因为多插入了一个数字,所以个数+1,这样处理的话,省去了pushup
if (l == r) return; //如果已经到了叶子节点,上面的操作就足够了,可以直接返回,否则需要继续向下递归
int mid = (l + r) >> 1;
if (x <= mid)
insert(tr[u].l, l, mid, x); //因为tr[u]进入本函数时,最先把旧的复制过来,所以tr[u].l也是上一个版本的左儿子节点
else
insert(tr[u].r, mid + 1, r, x);
}
int query(int p, int q, int l, int r, int x) {
if (l == r) return l;
int mid = (l + r) >> 1;
//使用*2的办法,成功的躲开了除以2可能会丢失精度的问题
//对位相减
if (2 * (tr[tr[q].l].cnt - tr[tr[p].l].cnt) > x)
return query(tr[p].l, tr[q].l, l, mid, x);
if (2 * (tr[tr[q].r].cnt - tr[tr[p].r].cnt) > x)
return query(tr[p].r, tr[q].r, mid + 1, r, x);
return 0;
}
int main() {
//文件输入输出
#ifndef ONLINE_JUDGE
freopen("P3567.in", "r", stdin);
#endif
n = read(), m = read();
// 0号版本没有内容时,主席树是不需要进行build的,强行build时,可能会有部分测试点TLE
// 0号版本有内容时,主席树是需要build的,不build,初始值无法给上
for (int i = 1; i <= n; i++) {
//不断的读入数字,不断的加入到主席树中,不断的创新新的版本
//新版本按套路来看,都要先从上一个版本中继承过来
int x = read();
root[i] = root[i - 1];
//依托于旧版本,插入数字x,并且,由于第一个参数是按地址引用的,所以新生成的节点号,会重写到root[i]
insert(root[i], 1, n, x);
}
while (m--) {
int l = read(), r = read();
printf("%d\n", query(root[l - 1], root[r], 1, n, r - l + 1));
}
return 0;
}