P3567 [POI2014]KUR-Couriers (主席树查询区间数大于一半的数)

题意:给一个数列,每次询问一个区间内有没有一个数出现次数超过一半
思路:主席树模板

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 5e5 + 10;
int n, m, a[N], root[N], cnt;
struct node {
    int l, r, num;
} zxs[N * 40];
void add(int l, int r, int pre, int &now, int pos) {
    zxs[++cnt] = zxs[pre], now = cnt, zxs[now].num++;
    if(l == r)
        return;
    int m = l + r >> 1;
    if(pos <= m)
        add(l, m, zxs[pre].l, zxs[now].l, pos);
    else
        add(m + 1, r, zxs[pre].r, zxs[now].r, pos);
}
int query(int l, int r, int L, int R, int k) {
    if(l == r)
        return l;
    int m = l + r >> 1;
    if(2 * (zxs[zxs[R].l].num - zxs[zxs[L].l].num) > k)
        return query(l, m, zxs[L].l, zxs[R].l, k);
    if(2 * (zxs[zxs[R].r].num - zxs[zxs[L].r].num) > k)
        return query(m + 1, r, zxs[L].r, zxs[R].r, k);
    return 0;
}
int main() {
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; i++) {
        scanf("%d", &a[i]);
        add(1, n, root[i - 1], root[i], a[i]);
    }
    for(int l, r, i = 0; i < m; i++) {
        scanf("%d%d", &l, &r);
        int ans = query(1, n, root[l - 1], root[r], (r - l + 1));
        printf("%d\n", ans);
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值