P3567 [POI 2014] KUR-Couriers

题目链接
题意:
给一个数列,每次询问一个区间内有没有一个数出现次数超过一半。
思路:
首先,如果一个区间内有一个数出现次数超过了一半,那么它一定是中位数。所以我们只需找到这个区间的中位数,然后判断这个数字出现的次数是否超过一半即可。实现的话用主席树寻找一个区间的中位数,判断次数可以用二分查找。具体实现见代码。

点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
const int N = 5e5+5;
#define lc(x) tr[x].l
#define rc(x) tr[x].r
struct Tree{
    int l,r,s;
}tr[N*23]; //N*(logN+3) 
int root[N],idx;
int arr[N];
vector<int> b;
void build(int &x,int l,int r){
    x=++idx;
    if(l==r) return ;
    int mid=l+r>>1;
    build(lc(x),l,mid);
    build(rc(x),mid+1,r);
}
void insert(int x,int &y,int l,int r,int k){
    y=++idx; tr[y]=tr[x]; tr[y].s++;
    if(l==r) return ;
    int mid=l+r>>1;
    if(k<=mid) insert(lc(x),lc(y),l,mid,k);
    else insert(rc(x),rc(y),mid+1,r,k);
}
int query(int x,int y,int l,int r,int k){
    if(l==r) return l;
    int mid=l+r>>1;
    int s=tr[lc(y)].s-tr[lc(x)].s;
    if(k<=s) return query(lc(x),lc(y),l,mid,k);
    else return query(rc(x),rc(y),mid+1,r,k-s);
}
map<int,vector<int>>mp;
signed main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int n,q;
    cin>>n>>q;
    for(int i=1;i<=n;++i){
        cin>>arr[i];
        mp[arr[i]].push_back(i);
        b.push_back(arr[i]);
    }
    sort(b.begin(),b.end());
    b.erase(unique(b.begin(),b.end()),b.end());
    int bn=b.size();
    build(root[0],1,bn);
    for(int i=1;i<=n;++i){
        int id=lower_bound(b.begin(),b.end(),arr[i])-b.begin()+1;
        insert(root[i-1],root[i],1,bn,id);
    }
    while(q--){
        int l,r;
        cin>>l>>r;
        int len=r-l+1;
        int k=(len>>1)+1;
        int id=query(root[l-1],root[r],1,bn,k)-1;
        int x=b[id];
        auto it=lower_bound(mp[x].begin(),mp[x].end(),l);
        auto it1=upper_bound(mp[x].begin(),mp[x].end(),r);
        if(it==it1){
            cout<<0<<endl;
            continue;
        }
        it1--;
        int c=it1-it+1;
        if(c>(double)(len/2.0)){
            cout<<x<<endl;
        }else{
            cout<<0<<endl;
        }
    }
    return 0;
}
posted @ 2025-03-09 22:02  sjgigj  阅读(29)  评论(0)    收藏  举报