• 2019 Multi-University Training Contest 4 K-th Closest Distance(二分+主席树)


    题意:给你n个数和q次查询,查询[l , r] 内, | a[i] - p | 第k小的数

    思路:二分答案,check的话就判断[l , r]区间内,[p-mid,p+mid]区间内数的个数和k的关系,若大于,则往左半边找,若小于则往右半边找

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1e5+10;
    const int maxnn=1e6+10;
    int a[maxn],T[maxn],tot,n,q;
    struct node
    {
        int ls,rs,sum;
    }tree[maxnn*30];
    int build1(int l,int r)
    {
        int rt=++tot;
        tree[rt].sum=0;
        if(l!=r)
        {
            int mid=(l+r)>>1;
            tree[rt].ls=build1(l,mid);
            tree[rt].rs=build1(mid+1,r);
        }
        return rt;
    }
    int build2(int l,int r,int last,int val)
    {
        int rt=++tot;
        tree[rt]=tree[last];
        tree[rt].sum++;
        if(l!=r)
        {
            int mid=(l+r)>>1;
            if(val<=mid)
                tree[rt].ls=build2(l,mid,tree[last].ls,val);
            else
                tree[rt].rs=build2(mid+1,r,tree[last].rs,val);
        }
        return rt;
    }
    int query(int l,int r,int x,int ql,int qr)
    {
        if(ql<=l&&qr>=r)
            return tree[x].sum;
        int mid=(l+r)>>1;
        if(qr<=mid)
            return query(l,mid,tree[x].ls,ql,qr);
        else
            if(ql>=mid+1)
                return query(mid+1,r,tree[x].rs,ql,qr);
            else
                return query(l,mid,tree[x].ls,ql,qr)+query(mid+1,r,tree[x].rs,ql,qr);
    }
    int main(){
        int t,preans;
        scanf("%d",&t);
        while(t--)
        {
            tot=preans=0;
            scanf("%d%d",&n,&q);
            for(int i=1;i<=n;i++)
                scanf("%d",&(a[i]));
            T[0]=build1(1,maxnn);
            for(int i=1;i<=n;i++)
                T[i]=build2(1,maxnn,T[i-1],a[i]);
            while(q--)
            {
                int l,r,p,k,low=0,high=maxnn,mid;
                scanf("%d%d%d%d",&l,&r,&p,&k);
                l^=preans,r^=preans,p^=preans,k^=preans;
                while(low<=high)
                {
                    mid=(low+high)>>1;
                    int tmp=query(1,maxnn,T[r],max(1,p-mid),min(p+mid,maxnn))-query(1,maxnn,T[l-1],max(1,p-mid),min(p+mid,maxnn));
                    if(tmp>=k)
                        preans = mid,high=mid-1;
                    else
                        low=mid+1;
                }
                printf("%d
    ",preans);
            }
        }
        return 0;
    }
  • 相关阅读:
    RPD Volume 168 Issue 4 March 2016 评论1
    初步接触CERNVM
    java中重载与重写的区别
    第三节 java 函数
    第二节 java流程控制(循环结构)
    第二节 java流程控制(判断结构+选择结构)
    JAVA 对象引用,以及对象赋值
    Java学习笔记整理第一章 java基本数据类型、修饰符、运算符
    plantuml的使用
    力扣 第210题
  • 原文地址:https://www.cnblogs.com/eason9906/p/11754729.html
Copyright © 2020-2023  润新知