[BZOJ 3524][Poi2014]Couriers:可持久化线段树

点击这里查看原题

主席树,建立权值线段树进行查询

/*
User:Small
Language:C++
Problem No.:3524
*/
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int M=5e5+5;
int n,q,cnt,rt[M];
struct no{
    int ls,rs,sum;
}a[M*20];
void insert(int &rt,int pre,int l,int r,int pos){
    rt=++cnt;
    a[rt]=a[pre];
    a[rt].sum++;
    if(l==r) return;
    int mid=l+r>>1;
    if(pos<=mid) insert(a[rt].ls,a[pre].ls,l,mid,pos);
    else insert(a[rt].rs,a[pre].rs,mid+1,r,pos);
}
int query(int s,int t){
    int l=1,r=n,cnt=(t-s+1)/2;
    int x=rt[s-1],y=rt[t];
    while(l!=r){
        int mid=l+r>>1;
        if(a[y].sum-a[x].sum<=cnt) return 0;
        if(a[a[y].ls].sum-a[a[x].ls].sum>cnt){
            y=a[y].ls;
            x=a[x].ls;
            r=mid;
        }
        else if(a[a[y].rs].sum-a[a[x].rs].sum>cnt){
            y=a[y].rs;
            x=a[x].rs;
            l=mid+1;
        }
        else return 0;
    }
    return l;
}
int main(){
    freopen("data.in","r",stdin);//
    scanf("%d%d",&n,&q);
    for(int i=1;i<=n;i++){
        int x;
        scanf("%d",&x);
        insert(rt[i],rt[i-1],1,n,x);
    }
    while(q--){
        int l,r;
        scanf("%d%d",&l,&r);
        printf("%d\n",query(l,r));
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值