You have an array: a1, a2, , an and you must answer for some queries.
For each query, you are given an interval [L, R] and two numbers p and K. Your goal is to find the Kth closest distance between p and aL, aL+1, …, aR.
The distance between p and ai is equal to |p - ai|.
For example:
A = {31, 2, 5, 45, 4 } and L = 2, R = 5, p = 3, K = 2.
|p - a2| = 1, |p - a3| = 2, |p - a4| = 42, |p - a5| = 1.
Sorted distance is {1, 1, 2, 42}. Thus, the 2nd closest distance is 1.
Input
The first line of the input contains an integer T (1 <= T <= 3) denoting the number of test cases.
For each test case:
冘The first line contains two integers n and m (1 <= n, m <= 10^5) denoting the size of array and number of queries.
The second line contains n space-separated integers a1, a2, …, an (1 <= ai <= 10^6). Each value of array is unique.
Each of the next m lines contains four integers L’, R’, p’ and K’.
From these 4 numbers, you must get a real query L, R, p, K like this:
L = L’ xor X, R = R’ xor X, p = p’ xor X, K = K’ xor X, where X is just previous answer and at the beginning, X = 0.
(1 <= L < R <= n, 1 <= p <= 10^6, 1 <= K <= 169, R - L + 1 >= K).
Output
For each query print a single line containing the Kth closest distance between p and aL, aL+1, …, aR.
Sample Input
1
5 2
31 2 5 45 4
1 5 5 1
2 5 3 2
Sample Output
0
1
现在才写这篇博客有点晚了。当时做这道题的时候还不太会,现在想想大体上可以想明白了。
这种第k大或者第k小的问题就是主席树。但是这次是绝对值第k小,这就很懵逼。。我们二分去找答案,二分到一个值之后,在[0,1000000]这个区间里去看[p-mid,p+mid]这个区间内有多少个值,要是个数小于k说明需要扩大范围,要是大于k的话,就需要减少范围。但是要是等于k,也要去减少范围,因为我们需要去更精确这个值。
代码如下:

#include<bits/stdc++.h>
#define ll long long
using namespace std;const int maxx=1e5+100;
struct node{int l;int r;int num;
}p[maxx<<5];
int a[maxx],root[maxx];
int n,m,tot;inline int read()
{char ch = getchar(); int x = 0, f = 1;while(ch < '0' || ch > '9') {if(ch == '-') f = -1;ch = getchar();} while('0' <= ch && ch <= '9') {x = x * 10 + ch - '0';ch = getchar();} return x * f;
}
inline int build(int l,int r)
{int cur=++tot;p[cur].num=0;if(l==r) return cur;int mid=l+r>>1;p[cur].l=build(l,mid);p[cur].r=build(mid+1,r);return cur;
}
inline int update(int rot,int l,int r,int pos)
{int cur=++tot;p[cur]=p[rot];p[cur].num++;if(l==r) return cur;int mid=l+r>>1;if(pos<=mid) p[cur].l=update(p[rot].l,l,mid,pos);else p[cur].r=update(p[rot].r,mid+1,r,pos);return cur;
}
inline int query(int l,int r,int L,int R,int lrot,int rrot)
{if(l<=L&&R<=r) return p[rrot].num-p[lrot].num;int mid=L+R>>1;int ret=0;if(l<=mid) ret+=query(l,r,L,mid,p[lrot].l,p[rrot].l);if(r>mid) ret+=query(l,r,mid+1,R,p[lrot].r,p[rrot].r);return ret;
}
int main()
{int t,l,r,p,k;int ans;t=read();while(t--){tot=0;n=read(),m=read();for(int i=1;i<=n;i++) a[i]=read();//root[0]=build(1,1000000);for(int i=1;i<=n;i++) root[i]=update(root[i-1],1,1000000,a[i]);ans=0;while(m--){l=read(),r=read(),p=read(),k=read();l^=ans;r^=ans;p^=ans;k^=ans;int li=0,ri=1000000;while(li<=ri){int mid=li+ri>>1;if(query(max(1,p-mid),min(1000000,p+mid),1,1000000,root[l-1],root[r])>=k) {ri=mid-1;ans=mid;}else li=mid+1;}printf("%d\n",ans);}}return 0;
}

快速读入优化后只需要3000+ms,有时候读入优化真的很管用。。
努力加油a啊,(o)/~

K-th Closest Distance HDU - 6621(第k小绝对值+主席树+二分)相关推荐

  1. HDU - 6621 K-th Closest Distance——主席树+二分

    [题目描述] HDU - 6621 K-th Closest Distance [题目分析] 因为看到第kkk大的要求,刚开始的时候一直都在想怎么运用第kkk大来解决问题,但是后来看其他人的博客才发现 ...

  2. hdu 4605 Magic Ball Game (在线主席树/离线树状数组)

    版权声明:本文为博主原创文章,未经博主允许不得转载. hdu 4605 题意: 有一颗树,根节点为1,每一个节点要么有两个子节点,要么没有,每个节点都有一个权值wi .然后,有一个球,附带值x . 球 ...

  3. Distance on the tree(树上倍增+主席树+树上差分+lca)南昌网络赛

    题目链接:南昌邀请赛网络赛Distance on the tree 统计一条链上边权小于k的边数. 树上差分,对于边权来说,一条链上的边的条数=sum[x]+sum[y]-2*sum[lca(x,y) ...

  4. HDU - 6278 Just $h$-index主席树+二分

    HDU - 6278 Just hhh-index [题目描述] [题目分析] 题目要求在区间[l,r][l,r][l,r]内大于h的数不少于h个,对于这种最大化问题,我们应该想到二分. 最小情况显然 ...

  5. HDU - 6704 K-th occurrence (后缀数组+主席树)

    题目链接 题意 QQQ次询问,每次询问求SSS的子串出现KKK次的位置 思路 刚开始想的是AC自动机,但是建自动机会超时,后来学长想到后缀数组+主席树的做法Orz...Orz...Orz... 出现K ...

  6. HDU - 3804 Query on a tree(主席树维护最大值+离散化)

    题目链接:点击查看 题目大意:给出一棵树,每条边上都有一个权值,给出m个查询:a,b:问从点1到点a的唯一路径上,在边权小于等于b的边中选出边权最大的值输出,若没有符合条件的边则输出-1: 题目分析: ...

  7. #HDU 4417 Super Mario (主席树 + 二分)

    Super Mario Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tota ...

  8. HDU - 6464 免费送气球(线段树二分)

    题意: 又到了GDUT一年一度的程序设计竞赛校赛的时间啦.同学们只要参加校赛,并且每解出一道题目就可以免费获得由ACM协会和集训队送出的气球一个.听到这个消息,JMC也想参加免费拿气球.可是,由于JM ...

  9. hdu 5592 ZYB's Premutation (线段树+二分查找)

    链接: http://acm.hdu.edu.cn/showproblem.php?pid=5592 Problem Description ZYB has a premutation P,but h ...

最新文章

  1. Rocksdb 的优秀代码(二)-- 工业级 打点系统 实现分享
  2. 这些 Shell 分析服务器日志命令集锦,收藏好
  3. 哈工大中文信息处理_【NLP】哈工大车万翔教授 自然语言处理NLPer的核心竞争力是什么?19页ppt...
  4. 在RHEL 5中Yum应用大全
  5. Token 认证的来龙去脉
  6. 将系统默认记事本替换成自己喜欢的文本编辑器
  7. 计算机系统-理论-运行时堆栈/栈顶
  8. 【python基础语法】列表的查询操作(包括切片)
  9. 偶尔看到的c11新特性1
  10. Visual Studio 2017入门教程丨如何运行一个Fortran程序
  11. Solidity教程一
  12. vue 下载文件,文件损坏无法打开
  13. R语言基于mgcv包进行广义可加模型及交互作用演示(2)
  14. 不平衡数据对于卷积神经网络的影响
  15. 微信域名防封的3种方案
  16. 机器学习实战之信用卡诈骗(一)
  17. deepin更新依赖错误_Ubuntu安装deepin-wine解决依赖问题
  18. 【干货分享】使用Inno Setup设计扁平化风格的安装包
  19. int java 声明_怎样用java定义一个int数组 C++ 怎么声明一个整型数组?
  20. 你对Web3的迅速发展一无所知,逃离大厂去拥抱Web3

热门文章

  1. IOS开发基础之屏幕组件适配添加约束
  2. python if else break_Python的for和break循环结构中使用else语句的技巧
  3. opencvsharp打开相机并视频显示
  4. 大锅菜机器人_炒菜机器人——烹饪界的一场革命
  5. lamda过滤_java 使用Lambda和filter对对象集合过滤
  6. Qt::WA_NoMousePropagation用法
  7. Android开发之跨进程通信-广播跨进程实现方法(附源码)
  8. 2021年本溪高考成绩查询,2021年本溪高考状元名单公布 今年本溪高考状元是谁资料和分数...
  9. 线程间通信: Handler , Looper, MessageQueue, Message (完结)
  10. 牵引力教育就业数据显示:很多大学毕业就等于失业?