HDU 6621 (2019杭电第四场 1008) K-th Closest Distance (主席树 + 二分)

题目

K-th Closest Distance
http://acm.hdu.edu.cn/showproblem.php?pid=6621

题意

给一个数组,每次给 l ,r, p, k,问区间 [l, r] 的数与 p 的绝对值的第 k 小,这个绝对值答案ans是多少。然后每次算出ans后,每次一的 l ,r, p, k都要取和ans异或出来的的值。l ^= ans, r ^= ans, p ^= ans, k ^= ans。ans一开始默认为0

题解

看到区间求第k小很容易想到用主席树,我们先设ans就是我二分的时候要找到的答案,那么就有 | p - an | = ans, 则有两种情况 p - an = ans , an - p = ans, 那么可以确定 an 的值域 [ p - ans, p + ans ]。
我们可以查询区间<= k 的数的个数,然后分别查询这两个值,做差就得到了 [p - ans, p + ans] 中有多少个数,如果个数 >= k,这个ans就是合法的。

代码

#include<stdio.h>
#include<vector>
#include<algorithm>
#include<math.h>
#define ll long long
using namespace std;
const int maxn = 2e5+5;
const int INF = 1e6+7;
struct node{
    int l,r,sum;
}hjt[maxn*55];
int cnt,root[maxn]; 
int a[maxn];
void insert(int l,int r,int pre,int &now,int p)
{
    hjt[++cnt] = hjt[pre];
    now = cnt;
    hjt[now].sum++;
    if(l==r) return;
    int mid = (l+r)>>1;
    if(p<=mid) insert(l,mid,hjt[pre].l,hjt[now].l,p);
    else insert(mid+1,r,hjt[pre].r,hjt[now].r,p);
}
int query(int l,int r,int L,int R,int x,int y)
{
	if(x <= l && r <= y)
		return hjt[R].sum - hjt[L].sum;
	int mid = (l+r) >> 1;
	int res = 0;
	if(x <= mid)
	{
		res += query(l,mid,hjt[L].l,hjt[R].l,x,y);
	}
	if(y > mid)
	{
		res += query(mid+1,r,hjt[L].r,hjt[R].r,x,y);
	}
	return res;
}
int main()
{
    int n,m;
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d %d",&n,&m);
        for(int i=1;i<=n;i++)
        {
			scanf("%d",&a[i]);
            insert(1,INF,root[i-1],root[i],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 pl = 0, pr = INF;
            while(pl <= pr)
            {
            	int mid = (pl + pr) >> 1;
            	if(query(1,INF,root[l-1],root[r],max(1, p - mid), min(INF, p + mid)) >= k)
            	{
            		ans = mid;
            		pr = mid-1;
				}
				else
					pl = mid+1;
			}
            printf("%d\n",ans);
        }
    }
    return 0;
 } 
发布了51 篇原创文章 · 获赞 16 · 访问量 3366

猜你喜欢

转载自blog.csdn.net/weixin_43911945/article/details/100901593