• 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;
    }
    
  • 相关阅读:
    NX二次开发-UFUN根据矩阵移动或复制对象uf5947
    NX二次开发-UFUN判断两个向量是否相等UF_VEC3_is_equal
    移动端开发小技巧
    echarts对后端返回的数据进行处理
    Vue router / Element 重复点击导航路由报错解决方法
    谷歌浏览器设置跨域问题
    setLocalStorage的存入与读取
    关于layui中数据表格的使用心得
    npm scss安装错误
    鼠标右键获取页面的坐标
  • 原文地址:https://www.cnblogs.com/acerkoo/p/11305368.html
Copyright © 2020-2023  润新知