zoukankan      html  css  js  c++  java
  • HDU6621 K-th Closest Distance HDU2019多校训练第四场 1008(主席树+二分)

    HDU6621 K-th Closest Distance HDU2019多校训练第四场 1008(主席树+二分)

    传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6621

    题意:

    给你n个数,有m次询问

    每次问你在区间[l,r]内 第k小的|(a_i-p)|是多少

    题解:

    主席树+二分

    每次二分答案

    如果p+mid到p-mid的值的个数大于k个的话,mid值就是可行了,然后缩小区间往左找即可

    因为保证有解,所以二分出来的mid值就是答案了

    query查的是权值在区间[p-mid,p+mid]内数的个数

    主席树的sum就是用来统计权值个数的

    注意不要被k给坑了,枚举第k小的数会T到爆的(QAQ)

    AC单组复杂度分析 :1e5*log(1e6)*log(1e6);

    TLE单组复杂度分析:1e5*169*2*log(1e6);

    代码:

    #include <set>
    #include <map>
    #include <stack>
    #include <cmath>
    #include <queue>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    typedef long long LL;
    typedef pair<int, int> pii;
    typedef unsigned long long uLL;
    #define ls rt<<1
    #define rs rt<<1|1
    #define lson l,mid,rt<<1
    #define rson mid+1,r,rt<<1|1
    #define bug printf("*********
    ")
    #define FIN freopen("input.txt","r",stdin);
    #define FON freopen("output.txt","w+",stdout);
    #define IO ios::sync_with_stdio(false),cin.tie(0)
    #define debug1(x) cout<<"["<<#x<<" "<<(x)<<"]
    "
    #define debug2(x,y) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<"]
    "
    #define debug3(x,y,z) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<" "<<#z<<" "<<z<<"]
    "
    const int maxn = 3e5 + 5;
    const int INF = 0x3f3f3f3f;
    const int mod = 1e9 + 7;
    const double Pi = acos(-1);
    LL gcd(LL a, LL b) {
        return b ? gcd(b, a % b) : a;
    }
    LL lcm(LL a, LL b) {
        return a / gcd(a, b) * b;
    }
    double dpow(double a, LL b) {
        double ans = 1.0;
        while(b) {
            if(b % 2)ans = ans * a;
            a = a * a;
            b /= 2;
        } return ans;
    }
    LL quick_pow(LL x, LL y) {
        LL ans = 1;
        while(y) {
            if(y & 1) {
                ans = ans * x % mod;
            } x = x * x % mod;
            y >>= 1;
        } return ans;
    }
    struct Tree {
        int l, r, sum;
    } T[maxn * 40];
    int cnt, n, m;
    int a[maxn];
    int root[maxn];
    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(pos <= mid) 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(k==0) return 0;
        if(l == r) return T[y].sum - T[x].sum;
        int mid = (l + r) >> 1;
        if (k <= mid)return query(l, mid, T[x].l, T[y].l, k);
        else {
            int ans = query(mid + 1, r, T[x].r, T[y].r, k);
            ans += T[T[y].l].sum - T[T[x].l].sum;
            return ans;
        }
    }
    int main() {
    
        int T;
        scanf("%d", &T);
        while(T--) {
            cnt = 0;
            scanf("%d%d", &n, &m);
    
            for(int i = 1; i <= n; i++) {
                scanf("%d", &a[i]);
            }
            int N = 1000000;
            for(int i = 1; i <= n; i++) {
                update(1, N, root[i], root[i - 1], a[i]);
            }
            int x, y, p, k;
            int ans = 0;
            for(int i = 1; i <= m; i++) {
                scanf("%d%d%d%d", &x, &y, &p, &k);
                x ^= ans;
                y ^= ans;
                if(x > y) swap(x, y);
                p ^= ans;
                k ^= ans;
                int l = 0, r = N;
                while(l <= r) {
                    int mid = (l + r) >> 1;
                    int R = min(N, p + mid);
                    int L = max(0, p - mid - 1);
                    if(query(1, N, root[x - 1], root[y], R) -
                            query(1, N, root[x - 1], root[y], L) >= k) {
                        ans = mid;
                        r = mid - 1;
                    } else {
                        l = mid + 1;
                    }
                }
                /*
                 while (L <= R) {
                    mid = (L + R) >> 1;
                    if (query(1, N, root[l - 1], root[r], min(p + mid, N)) -
                        query(1, N, root[l - 1], root[r], max(p - mid - 1, 0)) >= k)
                        ans = mid, R = mid - 1;
                    else L = mid + 1;
                }*/
                printf("%d
    ", ans);
            }
        }
        return 0;
    }
    
  • 相关阅读:
    【前端】用百度BAE和express部署自己的node后台
    【前端】JavaScript中prototype和__proto__的区别
    【其他】Objective-C 内存管理学习总结
    【Unity3D】Unity3D 让角色的头部望向鼠标
    【Unity3D】Unity3D 摄像机带透明截图
    【前端】前端冷知识
    【Unity3D】Unity3D SkinnedMeshRenderer换装系统
    【前端】HTML中最适合做按钮的元素
    IEnumerable和IEnumerator 详解 分类: C# 2014-12-05 11:47 18人阅读 评论(0) 收藏
    LINQ to Entities
  • 原文地址:https://www.cnblogs.com/buerdepepeqi/p/11279014.html
Copyright © 2011-2022 走看看