zoukankan      html  css  js  c++  java
  • HDU

    K-th Closest Distance

    主席树第二波~

    题意

    给你(n)个数(m)个询问,问(iin [l,r])计算每一个(|a_{i}-p|)求出第(k)
    题目要求强制在线(l = l oplus ans、r = r oplus ans、p = p oplus ans、k = k oplus ans)(ans为上次询问的答案)

    思路

    • 二分答案(ans),找区间(iin[l,r], a_{i} in [p-ans, p+ans])里的数量(>= k)
      (|a_{i} - p | = ans)
      (a_{i} - p = ans、p - a_{i} = ans)
      (a_{i} = ans + p、a_{i} = p - ans)
    • 用主席树维护一下就(ok)

    AC代码

    
    #include <map>
    #include <set>
    #include <list>
    #include <ctime>
    #include <cmath>
    #include <stack>
    #include <queue>
    #include <cfloat>
    #include <string>
    #include <vector>
    #include <cstdio>
    #include <bitset>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define  lowbit(x)  x & (-x)
    #define  mes(a, b)  memset(a, b, sizeof a)
    #define  fi         first
    #define  se         second
    #define  pii        pair<int, int>
    
    typedef unsigned long long int ull;
    typedef long long int ll;
    const int    maxn = 1e5 + 10;
    const int    maxm = 1e5 + 10;
    const ll     mod  = 1e9 + 7;
    const ll     INF  = 1e18 + 100;
    const int    inf  = 0x3f3f3f3f;
    const double pi   = acos(-1.0);
    const double eps  = 1e-8;
    using namespace std;
    
    int n, m;
    int cas, tol, T;
    struct Node{
        int l, r, cnt;
    }node[maxn*40];
    int w[maxn], a[maxn];
    vector<int> v;
    
    void init(){
        v.clear();
        tol = 0;
        mes(w, 0);
    }
    
    void build(int l, int r, int rt){
        rt = ++tol;
        node[rt].cnt = 0;
        if(l == r)
            return;
        int mid = l+r>>1;
        build(l, mid, node[rt].l);
        build(mid+1, r, node[rt].r);
    }
    
    void update(int l, int r, int &x, int y, int pos){
        x = ++tol;
        node[x] = node[y];
        node[x].cnt++;
        if(l == r)
            return;
        int mid = l+r>>1;
        if(pos <= mid)
            update(l, mid, node[x].l, node[y].l, pos);
        else
            update(mid+1, r, node[x].r, node[y].r, pos);
    }
    
    
    int query(int L, int R, int l, int r, int x, int y){
        if(L <= l && r <= R)
            return node[y].cnt - node[x].cnt;
        int mid = l+r>>1, ans = 0;
        if(L <= mid)
            ans += query(L, R, l, mid, node[x].l, node[y].l);
        if(R > mid)
            ans += query(L, R, mid+1, r, node[x].r, node[y].r);
        return ans;
    }
    
    int getid(int x){
        return lower_bound(v.begin(), v.end(), x) - v.begin()+1;
    }
    int getid_(int x){
        return upper_bound(v.begin(), v.end(), x) - v.begin()+1;
    }
    
    int main() {
        scanf("%d", &T);
        while(T--){
            scanf("%d%d", &n, &m);
            init();
            for(int i = 1; i <= n; i++){
                scanf("%d", &a[i]);
                v.push_back(a[i]);
            }
            sort(v.begin(), v.end());
            v.erase(unique(v.begin(), v.end()), v.end());
            int len = v.size()+1;
            build(1, len, 1);
            for(int i = 1; i <= n; i++)
                update(1, n, w[i], w[i-1], getid(a[i]));
            int ans = 0;
            while(m--){
                int L, R, p, k;
                scanf("%d%d%d%d", &L, &R, &p, &k);
                L ^= ans; R ^= ans; p^= ans;k ^= ans;   //要记得^
                int l = 0, r = 1e6;
                while(l <= r){
                    int mid = (l+r)>>1;
                    int sum = query(getid(p-mid), getid_(p+mid)-1, 1, n, w[L-1], w[R]);     //第一个getid和第二个不一样
                    if(sum >= k){
                        ans = mid;
                        r = mid-1;
                    }
                    else
                        l = mid+1;
                }
                printf("%d
    ", ans);
            }
        }
        return 0;
    }
    
    
    
  • 相关阅读:
    HTML DOM教程 14HTML DOM Document 对象
    HTML DOM教程 19HTML DOM Button 对象
    HTML DOM教程 22HTML DOM Form 对象
    HTML DOM教程 16HTML DOM Area 对象
    ubuntu 11.04 问题 小结
    VC6.0的 错误解决办法 小结
    boot.img的解包与打包
    shell里 截取字符串
    从零 使用vc
    Imagemagick 对图片 大小 和 格式的 调整
  • 原文地址:https://www.cnblogs.com/zhuyou/p/11291729.html
Copyright © 2011-2022 走看看