zoukankan      html  css  js  c++  java
  • HDU 6621 K-th Closest Distance(主席树+二分)

    题意

    对于大小为n的正整数数组a,有q次询问,每次询问给出整数数p、k,要求输出离p第k近的数字,强制在线。

    思路

    主席树维护区间 ([l, r]) 数字出现次数,二分答案。

    Code

    	#include <bits/stdc++.h>
    
    using namespace std;
    typedef long long ll;
    const int maxn = 1e5+10;
    
    struct node {
        int l, r, val;
    }tr[maxn*21];
    int root[maxn], tot, a[maxn], b[maxn];
    
    void build(int l, int r, int &x) {
        x = ++tot;
        if(l==r) return;
        int mid = l+r>>1;
        build(l, mid, tr[x].l); build(mid+1, r, tr[x].r);
    }
    void update(int l, int r, int x, int &y, int p, int val=1) {
        y = ++tot;
        tr[y] = tr[x];
        tr[y].val += val;
    //    cout << l << " " << r << " " <<  tr[y].val << endl;
        if(l==r) return;
        int mid = l+r>>1;
        if(p<=mid) update(l, mid, tr[x].l, tr[y].l, p, val);
        else update(mid+1, r, tr[x].r, tr[y].r, p, val);
    }
    int query(int l, int r, int x, int y, int L, int R) {
        if(L<=l && r<=R) return tr[y].val-tr[x].val;
        int mid=l+r>>1, ans=0;
        if(L<=mid) ans=query(l, mid, tr[x].l, tr[y].l, L, R);
        if(R>mid) ans+=query(mid+1, r, tr[x].r, tr[y].r, L, R);
        return ans;
    }
    int T, n, m;
    void read(int &x) {
        x=0; char ch, c=getchar();
        while(c<'0' || c>'9') ch=c, c=getchar();
        while(c>='0' && c<='9') x=x*10+c-'0', c=getchar();
        if(ch=='-') x=-x;
    }
    
    int main() {
    //    freopen("in.txt", "r", stdin);
        scanf("%d", &T);
        while(T--) {
            scanf("%d%d", &n, &m);
            tot=0;
            build(1, maxn, root[0]);
            for (int i=1; i<=n; ++i) {
                scanf("%d", a + i);
                b[i] = a[i];
            }
            sort(b+1, b+1+n);
            int cnt = unique(b+1, b+1+n)-b-1;
            for (int i=1; i<=n; ++i) {
                a[i] = lower_bound(b+1, b+cnt+1, a[i])-b+1;
                update(1, maxn, root[i-1], root[i], a[i]);
            }
            int ans=0;
            for (int L, R, P, K, i=1; i<=m; ++i) {
                scanf("%d%d%d%d", &L, &R, &P, &K);
                L^=ans, R^=ans, P^=ans, K^=ans;
                if(L>R) swap(L, R);
                int l=0, r=1e6+10;
                while(l<r) {
                    int mid=l+r>>1;
                    int ll = lower_bound(b+1, b+1+cnt, P-mid)-b+1;
                    int rr = upper_bound(b+1, b+1+cnt, P+mid)-b;
                    int sum = query(1, maxn, root[L-1], root[R], ll, rr);
                    if(sum >= K) r=mid;
                    else l=mid+1;
                }
                printf("%d
    ", l);
                ans = l;
            }
        }
        return 0;
    }
    
  • 相关阅读:
    ios UIWebView截获html并修改便签内容(转载)
    IOS获取系统时间 NSDate
    ios 把毫秒值转换成日期 NSDate
    iOS  如何判断当前网络连接状态  网络是否正常  网络是否可用
    IOS开发 xcode报错之has been modified since the precompiled header was built
    iOS系统下 的手机屏幕尺寸 分辨率 及系统版本 总结
    iOS 切图使用 分辨率 使用 相关总结
    整合最优雅SSM框架:SpringMVC + Spring + MyBatis 基础
    Java面试之PO,VO,TO,QO,BO
    Notes模板说明
  • 原文地址:https://www.cnblogs.com/acerkoo/p/11305368.html
Copyright © 2011-2022 走看看