2019hdu 멀티 학교 K 번째 가장 가까운 거리

주제 링크 : 여기를 클릭 벽지

질문의 대략 의미 : Q 시간이 당신에게 각 시간 간격을 물어 물어 [L, R]의 | P-인공 지능 | K-값이 훨씬 작습니다

해결책:

그것은 우리가 절반 답을 고려, 직접 찾기 어려운,이 문제는 매우 간단합니다

우리는 무게의 나무 회장의 숫자만큼의 무게 각 쿼리 간격 번호 [L, R] [P-중반, P + 중간]이 라인에의 유지

암호:

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+1;
int n,m,maxn,lst,L,R,k,p,a[N];
int rt[N],sz[N*40];
int tot,ls[N*40],rs[N*40];
int read(){
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-f;ch=getchar();}
    while(isdigit(ch)){x=x*10+ch-48;ch=getchar();}
    return x*f;
}
void build(int &q,int l,int r){
    q=++tot;sz[q]=0;
    if(l==r) return ;
    int mid=l+r>>1;
    build(ls[q],l,mid);
    build(rs[q],mid+1,r);
}
void ins(int &q,int lst,int l,int r,int x){
    q=++tot;sz[q]=sz[lst]+1;
    ls[q]=ls[lst],rs[q]=rs[lst];
    if(l==r) return ;
    int mid=l+r>>1;
    if(mid>=x) ins(ls[q],ls[lst],l,mid,x);
    else ins(rs[q],rs[lst],mid+1,r,x);
}
int query(int q,int lst,int l,int r,int x,int y){
    if(l>=x&&r<=y) return sz[q]-sz[lst];
    int mid=l+r>>1,re=0;
    if(mid>=x) re+=query(ls[q],ls[lst],l,mid,x,y);
    if(mid<y) re+=query(rs[q],rs[lst],mid+1,r,x,y);
    return re;
}
int check(int x){
    int l=max(0,p-x),r=min(maxn,p+x);
    int v=query(rt[R],rt[L-1],1,maxn,l,r);
    return v>=k;
}
void solve(){
    maxn=lst=tot=0;
    n=read(),m=read();
    for(int i=1;i<=n;i++){
        a[i]=read();
        maxn=max(maxn,a[i]);
    }build(rt[0],1,maxn);
    for(int i=1;i<=n;i++)
        ins(rt[i],rt[i-1],1,maxn,a[i]);
    for(int i=1;i<=m;i++){
        L=read(),R=read(),p=read(),k=read();
        L^=lst,R^=lst,p^=lst,k^=lst;
        int l=0,r=maxn,re=maxn;
        while(l<=r){
            int mid=l+r>>1;
            if(check(mid)) re=mid,r=mid-1;
            else l=mid+1;
        }printf("%d\n",re);lst=re;
    }
}
int main(){
    int t=read();
    while(t--) solve();
    return 0;
}

추천

출처www.cnblogs.com/NLDQY/p/11281121.html