#树状数组,线段树,离散#JZOJ 3854 分组
题目
Bsny所在的精灵社区有\(n\)个居民,每个居民有一定的地位和年龄,\(r_i\)表示第\(i\)个人的地位,\(a_i\)表示第\(i\)个人的年龄。
最近社区里要举行活动,要求几个人分成一个小组,小组中必须要有一个队长,要成为队长有这样的条件:
1、队长在小组中的地位应该是最高的(可以并列第一);
2、小组中其他成员的年龄和队长的年龄差距不能超过\(K\)。
有些人想和自己亲密的人组在同一个小组,同时希望所在的小组人越多越好。比如\(x\)和\(y\)想在同一个小组,同时希望它们所在的小组人越多越好,当然,它们也必须选一个符合上述要求的队长,那么问你,要同时包含\(x\)和\(y\)的小组,最多可以组多少人?
第一行两个整数\(n\)和\(K\);
接下来一行输入\(n\)个整数:\(r_1, r_2,\dots, r_n\)
接下来一行输入\(n\)个整数:\(a_1, a_2,\dots, a_n\)
接下来输入\(Q\)表示有\(Q\)个询问;
接下来\(Q\)行每行输入\(x, y\),表示询问:当\(x\)和\(y\)组在同一个小组,它们小组最多可以有多少人(\(x\)和\(y\)也有可能被选为队长,只要它们符合条件)。
对于每个询问,输出相应的答案,每个答案占一行。
当\(x\)和\(y\)无法在同一组时,输出-1(比如\(x\)的年龄是1, \(y\)的年龄是100,\(K=1\),无论谁当队长,\(x\)和\(y\)两者中,总会有人跟队长的年龄差距超过\(K\),那么输出-1)。
Sample Input
5 1
1 5 4 1 2
4 4 3 2 2
4
5 3
2 3
2 5
4 1
Sample Output
4
3
-1
4
分析
对于地位最高这个条件可以离线处理,枚举队长是谁以处理询问
先将年龄离散化,那么这个队长可以选的区间就是\([a_x-k\sim a_x+k]\)
答案就是两人选择区间的交集大小,可以用树状数组+线段树实现
代码
#include <cstdio>
#include <cctype>
#include <algorithm>
#include <vector>
#define rr register
using namespace std;
const int N=100011;
struct rec{int w,c,rk;}a[N];
int n,m,b[N],k,l[N],r[N],pos[N],ans[N],Rk[N],bas=1; vector<int>K[N];
inline signed min(int a,int b){return a<b?a:b;}
inline signed max(int a,int b){return a>b?a:b;}
struct zkw{
int w[N*3];
inline void build(int n){
for (;(bas<<=1)<n+2;);
for (rr int i=1;i<=bas*2;++i) w[i]=-1;
}
inline void update(int x,int z){
x+=bas,w[x]=max(w[x],z);
for (x>>=1;x;x>>=1) w[x]=max(w[x<<1],w[x<<1|1]);
}
inline signed query(int l,int r){
rr int ans=-1;
for (l+=bas-1,r+=bas+1;l^r^1;l>>=1,r>>=1){
if (!(l&1)) ans=max(ans,w[l^1]);
if (r&1) ans=max(ans,w[r^1]);
}
return ans;
}
}T;
struct Tree_Array{
int c[N];
inline void update(int x,int y){
for (;x<=n;x+=-x&x) c[x]+=y;
}
inline signed query(int x){
rr int ans=0;
for (;x;x-=-x&x) ans+=c[x];
return ans;
}
}C;
inline signed iut(){
rr int ans=0; rr char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans;
}
inline void print(int ans){
if (ans<0) putchar('-'),ans=-ans;
if (ans>9) print(ans/10);
putchar(ans%10+48);
}
bool cmp(rec x,rec y){return x.c>y.c;}
signed main(){
n=iut(),k=iut();
for (rr int i=1;i<=n;++i) a[i].c=iut(),a[i].rk=i;
for (rr int i=1;i<=n;++i) a[i].w=iut(),b[i]=a[i].w;
sort(b+1,b+1+n),m=unique(b+1,b+1+n)-b-1,sort(a+1,a+1+n,cmp),T.build(m);
for (rr int i=1;i<=n;++i){
l[i]=lower_bound(b+1,b+1+m,a[i].w-k)-b,r[i]=upper_bound(b+1,b+1+m,a[i].w+k)-b-1;
Rk[a[i].rk]=i,C.update(a[i].w=lower_bound(b+1,b+1+m,a[i].w)-b,1);
}
rr int Test=iut();
for (rr int i=1;i<=Test;++i){
rr int x=Rk[iut()],y=Rk[iut()];
if (x<y) x^=y,y^=x,x^=y;
K[y].push_back(i),pos[i]=x;
}
for (rr int i=1,p=1;i<=n;++i){
for (;p<=n&&a[p].c>=a[i].c;++p) T.update(a[p].w,C.query(r[p])-C.query(l[p]-1));
for (rr int j=0;j<K[i].size();++j){
rr int x=pos[K[i][j]],y=i;
rr int L=max(l[x],l[y]),R=min(r[x],r[y]);
if (L>R) ans[K[i][j]]=-1;
else ans[K[i][j]]=T.query(L,R);
}
C.update(a[i].w,-1);
}
for (rr int i=1;i<=Test;++i) print(ans[i]),putchar(10);
return 0;
}
#树状数组,线段树,离散#JZOJ 3854 分组的更多相关文章
- 洛谷P2414 阿狸的打字机 [NOI2011] AC自动机+树状数组/线段树
正解:AC自动机+树状数组/线段树 解题报告: 传送门! 这道题,首先想到暴力思路还是不难的,首先看到y有那么多个,菜鸡如我还不怎么会可持久化之类的,那就直接排个序什么的然后按顺序做就好,这样听说有7 ...
- 树状数组 && 线段树应用 -- 求逆序数
参考:算法学习(二)——树状数组求逆序数 .线段树或树状数组求逆序数(附例题) 应用树状数组 || 线段树求逆序数是一种很巧妙的技巧,这个技巧的关键在于如何把原来单纯的求区间和操作转换为 求小于等于a ...
- hdu1394(枚举/树状数组/线段树单点更新&区间求和)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1394 题意:给出一个循环数组,求其逆序对最少为多少: 思路:对于逆序对: 交换两个相邻数,逆序数 +1 ...
- hdu 1166:敌兵布阵(树状数组 / 线段树,入门练习题)
敌兵布阵 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submis ...
- hdu 5147 Sequence II【树状数组/线段树】
Sequence IITime Limit: 5000/2500 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Problem ...
- 数据结构--树状数组&&线段树--基本操作
随笔目的:方便以后对树状数组(BIT)以及基本线段树的回顾 例题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1166 例题:hdu 1166 敌兵布阵 T ...
- BZOJ_1901_&_ZJU_2112_Dynamic_Rankings_(主席树+树状数组/线段树+(Treap/Splay))
描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1901 给出一个长度为n的数列A,有m次询问,询问分两种:1.修改某一位置的值;2.求区间[l, ...
- BZOJ 3333 排队计划 树状数组+线段树
题目大意:给定一个序列.每次选择一个位置,把这个位置之后全部小于等于这个数的数抽出来,排序,再插回去,求每次操作后的逆序对数 首先我们每一次操作 对于这个位置前面的数 因为排序的数与前面的数位置关系不 ...
- 第十四个目标(dp + 树状数组 + 线段树)
Problem 2236 第十四个目标 Accept: 17 Submit: 35 Time Limit: 1000 mSec Memory Limit : 32768 KB Probl ...
- Curious Robin Hood(树状数组+线段树)
1112 - Curious Robin Hood PDF (English) Statistics Forum Time Limit: 1 second(s) Memory Limit: 64 ...
随机推荐
- Taurus.MVC WebMVC 入门开发教程3:数据绑定Model
前言: 在这篇 Taurus.MVC WebMVC 入门开发教程的第三篇文章中, 我们将重点介绍如何进行数据绑定操作,还会学习如何使用 ${属性名称} CMS 语法来绑定页面上的元素与 Model 中 ...
- 面试官:说一下红锁RedLock的实现原理?
RedLock 是一种分布式锁的实现算法,由 Redis 的作者 Salvatore Sanfilippo(也称为 Antirez)提出,主要用于解决在分布式系统中实现可靠锁的问题.在 Redis 单 ...
- 【LeetCode链表#8】翻转链表(双指针+递归)/K个一组翻转
翻转链表 力扣题目链接(opens new window) 题意:反转一个单链表. 示例: 输入: 1->2->3->4->5->NULL 输出: 5->4-> ...
- cw attack
- 代码随想录算法训练营第十三天| 239. 滑动窗口最大值 347.前 K 个高频元素 总结
239. 滑动窗口最大值 (一刷至少需要理解思路) 卡哥建议:之前讲的都是栈的应用,这次该是队列的应用了.本题算比较有难度的,需要自己去构造单调队列,建议先看视频来理解. 题目链接/文章讲解/视频讲解 ...
- Jmeter 如何连接mysql数据库?
1 首先安装jmeter jdbc 插件 JDBC驱动包下载教程:https://blog.csdn.net/qq_50896685/article/details/129154801 2 安装好后将 ...
- Vue实现图片瀑布流
在线演示地址:点击前往 一,创建一个Waterfall组件 代码如下: <template> <div class="waterfall"> <!-- ...
- Spring状态机(FSM),让订单状态流转如丝般顺滑
引言 在复杂的应用程序设计中,尤其是那些涉及多个状态变迁和业务流程控制的场景,有限状态机(Finite State Machine, FSM)是一种强大而有效的建模工具.Spring框架为此提供了Sp ...
- nexus 莫名错误 两个解决的地方
unknown org.sonatype.nexus.reposibory.httpclient.internal.httpclientfaceImpl 也没太解决,先记录下来吧
- C++学习笔记之指针引用
目录 指针 指针定义 左值与右值 指针数组与数组指针 const与指针 指针的指针 NULL指针 内存泄漏(Memory Leak)问题 智能指针 引用 指针 指针定义 指针定义的基本形式:指针本身就 ...