POI 2014 Couriers

窮源溯流發表於2020-10-03

 

詢問任意一個區間求是否有一個數在這個區間中出現次數嚴格大於一半,若有輸出其值,若沒有輸出 0

const int N=5e5+5;
 
    int n,m,t;
    int i,j,k;
    int a[N];
    vector<int> v;
    int root[N],cnt=0; //每一個根節點的編號  結點的個數
    struct Node
    {
        int l,r;
        int sum;
    }T[N*40];

int get_id(int x)
{
    return lower_bound(v.begin(),v.end(),x)-v.begin()+1;
}

void update(int l,int r,int &x,int y,int pos)
{
    T[++cnt]=T[y];
    T[cnt].sum++;
    x=cnt;
    if(l==r) return ;
    int mid=l+r>>1;
    if(mid>=pos) update(l,mid,T[x].l,T[y].l,pos);
    else update(mid+1,r,T[x].r,T[y].r,pos);
}

int query(int l,int r,int x,int y,int k)
{
    if(l==r)
    {
        if(T[y].sum-T[x].sum>k) return l;
        else return -1;
    }
    int L=T[T[y].l].sum-T[T[x].l].sum ;
    int R=T[T[y].r].sum-T[T[x].r].sum ;
    int mid=l+r>>1;
    if(L>k) return query(l,mid,T[x].l,T[y].l,k);
    else if(R>k) return query(mid+1,r,T[x].r,T[y].r,k);
    else return -1;
}

int main()
{
    //IOS;
    while(~sdd(n,m)){
        for(i=1;i<=n;i++){
            sd(a[i]);
            v.pb(a[i]);
        }
        sort(v.begin(),v.end());
        v.erase( unique(v.begin() ,v.end()),v.end() );
        for(i=1;i<=n;i++) update(1,n,root[i],root[i-1],get_id(a[i]));

        int x,y,k;
        while(m--){
            sdd(x,y);
            k=y-x+1>>1;
            int ans=query(1,n,root[x-1],root[y],k);
            if(ans==-1) pd(0);
            else pd(v[ans-1]);
        }
    }
    //PAUSE;
    return 0;
}