#树状数组,线段树,离散#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 ...
随机推荐
- golang泛型简介
linux下go版本安装(1.18.1版本) >>> wget https://go.dev/dl/go1.18.1.linux-amd64.tar.gz >>> ...
- java+mysql数据库实现的学生管理系统
说明: java+mysql数据库实现的学生管理系统 功能 实现增加学生.删除学生.修改学生.学生列表.查询学生功能 截图: 开发工具/技术 java eclipse 价格:50元,有需要联系 微信 ...
- yolov5项目cuda错误解决
CUDA报错解决 # 报错详情 AssertionError: CUDA unavailable, invalid device 0 requested 查看cuda版本 先看一下电脑是否支持GPU, ...
- 【Azure 应用服务】Azure Function Python函数部署到Azure后遇见 Value cannot be null. (Parameter 'receiverConnectionString') 错误
问题描述 使用VS Code创建Python Function,处理Event Hub中的数据.当部署到Azure Function App后,函数无法执行,查看 Function 日志出现 Valu ...
- 【Azure 应用服务】在创建Web App Service的时候,选Linux系统后无法使用Mysql in App
问题描述 如图上,是App Services在Windows环境中,系统自带了MySQL In App功能.而在,Linux环境中,没有发现Mysql in App功能,是不是无法在Linux中使用呢 ...
- UG474
为了对工程的资源利用率进行优化,我们首先需要知道当前工程对资源的利用率情况.在Vivado下,我们可以查看工程的资源利用率情况,在下面这张图中,其罗列出了整个工程所使用的资源情况.首先,下面我们需要一 ...
- C++ STL 容器-array类型
C++ STL 容器-array类型 array是C++11STL封装的数组,内存分配在栈中stack,绝对不会重新分配,随机访问 创建和初始化 // 下面的等同于int a[10]; std::ar ...
- 专访容智信息柴亚团:最低调的公司如何炼成最易用的RPA?
专访容智信息柴亚团:最低调的公司如何炼成最易用的RPA? 专访容智信息柴亚团:终极愿景是助力天下企业成为数字化孪生组织 文/王吉伟 6月,容智信息(容智)正式发布了全新的移动端RPA产品iBot Mo ...
- spingboot打造教育平台(谷粒学院课程笔记)
第一单fqb 申明,项目的框架技术架构,前端运行时node 后端框架spring 开发前准备:mysbatis官网随时看文档,IDEa 202编释器2 环境配置,idea配置一下mavem路 ...
- 快速复习JDBC(超详细)
第一章 JDBC概述 之前我们学习了JavaSE,编写了Java程序,数据保存在变量.数组.集合等中,无法持久化,后来学习了IO流可以将数据写入文件,但不方便管理数据以及维护数据的关系: 后来我们学 ...