【NOIP2014八校联考第2场第2试9.28】分组(group)

2024-05-29 03:08

本文主要是介绍【NOIP2014八校联考第2场第2试9.28】分组(group),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Description

Bsny所在的精灵社区有n个居民,每个居民有一定的地位和年龄,ri表示第i个人的地位,ai表示第i个人的年龄。
最近社区里要举行活动,要求几个人分成一个小组,小组中必须要有一个队长,要成为队长有这样的条件:
1、队长在小组中的地位应该是最高的(可以并列第一);
2、小组中其他成员的年龄和队长的年龄差距不能超过K。
有些人想和自己亲密的人组在同一个小组,同时希望所在的小组人越多越好。比如x和y想在同一个小组,同时希望它们所在的小组人越多越好,当然,它们也必须选一个符合上述要求的队长,那么问你,要同时包含x和y的小组,最多可以组多少人?

Input

第一行两个整数n和K;
接下来一行输入n个整数:r1, r2, …, rn
接下来一行输入n个整数:a1, a2, …, an
接下来输入Q表示有Q个询问;
接下来Q行每行输入x, y,表示询问:当x和y组在同一个小组,它们小组最多可以有多少人(x和y也有可能被选为队长,只要它们符合条件)。

Output

对于每个询问,输出相应的答案,每个答案占一行。
当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
【样例解释】
询问1:当第5个人和第3个人想在一组时,小组成员可以有{1, 3, 4, 5},选择3当队长,而2不可以加入,因为2加入的话,5和2的年龄差距为2,超过K=1了;
询问2:当第2个人和第3个人想在一组时,可以选择{1, 2, 3};
询问3:当2和5想在一起时,无法满足要求;
询问4:当4和1想在一起时,可以选择{1, 3, 4, 5};

Data Constraint

20%的数据:2≤n≤100,0≤ k≤100,1≤ ri, ai ≤100,1≤ q≤ 100;
40%的数据:2≤ n≤1000,0≤ k≤ 1000,1≤ ri, ai ≤ 1000,1≤ q≤ 1000;
60%的数据:2≤ n≤ 10^4,0≤ k≤ 10^9,1≤ ri, ai ≤ 10^9, 1≤ q≤ 10^4;
100%的数据:2≤ n≤ 10^5,0≤ k≤ 10^9,1≤ ri, ai ≤ 10^9,1≤ q≤ 10^5,1≤ x, y≤ n, x≠y。

Solution

这题看你的写题能力,而且PASCAL的准备多打至少三个快拍……

首先,需要求出每个人作为队长,队伍里的人数
先把人按照地位排序,对于一个人,到他时,所有地位比他小的人的年龄都已经加入了权值线段树(权值代表年龄),他的答案就是他可取的年龄范围内的人数
单点修改+区间查询,是(权值)线段树的基本操作,但由于区间过大,需要动态开节点
时间复杂度 O(nlog2(n))

接着求答案,由于询问比较多,需要离线
发现,对于两个人,x和y,可以做他们的队长的人z必定满足以下条件
1.r[z]>max(r[x],r[y])
2.max(a[x]k,a[y]k)<=a[z]<=min(a[x]+k,a[y]+k)
那么将每个询问按照 max(r[x],r[y]) 顺序从小到大排序,然后倒着做
每次进行询问前,将所有地位 >max(r[x],y[x]) 的人作为队长的队伍人数加入权值线段树中(权值还是年龄),然后查询 max(a[x]k,a[y]k)<=a[z]<=min(a[x]+k,a[y]+k) 中的队伍人数最大值
这也是(权值)线段树的基本操作,任然需要动态开节点
时间复杂度 O(nlog2(n))

Code

我认为我的程序算优美了,1800B,我看某些人3~5KB的人,同时偷笑

#include<cstdio>
#include<algorithm>
#include<cstring>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
#define N 101000
using namespace std;
int n,k,q,d[N],tot=1,ans[N],an;
struct node{int x,y,z,l;
}a[N],b[N];
struct nod1{int l,r,d,z;
}t[N*20];
bool cnt(node x,node y){return x.x<y.x;}
bool cmt(node x,node y){return x.z<y.z;}
void insert(int v,int i,int j,int x,int y,int z)
{if(z==0) t[v].d++;else t[v].d=max(t[v].d,y);if(i==j) return;int m=(i+j)/2;if(x<=m) if(!t[v].l) t[v].l=++tot;if(x>m) if(!t[v].r) t[v].r=++tot;if(x<=m) insert(t[v].l,i,m,x,y,z);else insert(t[v].r,m+1,j,x,y,z);
}
void get(int v,int i,int j,int x,int y,int z)
{if(x>y) return;if(i==x&&j==y){if(z==0) an+=t[v].d;else an=max(an,t[v].d);return;}int m=(i+j)/2;if(y<=m) get(t[v].l,i,m,x,y,z);else if(x>m) get(t[v].r,m+1,j,x,y,z);else get(t[v].l,i,m,x,m,z),get(t[v].r,m+1,j,m+1,y,z);
}
int main()
{freopen("group.in","r",stdin);freopen("group.out","w",stdout);scanf("%d%d",&n,&k);fo(i,1,n) scanf("%d",&a[i].x);fo(i,1,n) scanf("%d",&a[i].y),a[i].z=i;sort(a+1,a+n+1,cnt);int j=1;fo(i,1,n){for(;a[j].x==a[i].x;j++) insert(1,1,1000000000,a[j].y,0,0);an=0;get(1,1,1000000000,max(a[i].y-k,1),min(a[i].y+k,1000000000),0);d[a[i].z]=an;}sort(a+1,a+n+1,cmt);scanf("%d",&q);fo(i,1,q) {scanf("%d%d",&b[i].x,&b[i].y);b[i].z=max(a[b[i].x].x,a[b[i].y].x);b[i].x=a[b[i].x].y;b[i].y=a[b[i].y].y;b[i].l=i;}sort(b+1,b+q+1,cmt);sort(a+1,a+n+1,cnt);memset(t,0,sizeof(t));tot=1;int l=q;j=n;fd(i,q,1){for(;a[j].x>=b[i].z;j--) insert(1,1,1000000000,a[j].y,d[a[j].z],1);an=-1;get(1,1,1000000000,max(max(b[i].x-k,b[i].y-k),1),min(min(b[i].x+k,b[i].y+k),1000000000),1);ans[b[i].l]=an;}fo(i,1,q) if(ans[i]>0) printf("%d\n",ans[i]);else printf("-1\n");
}

这篇关于【NOIP2014八校联考第2场第2试9.28】分组(group)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1012468

相关文章

使用Python在Excel中创建和取消数据分组

《使用Python在Excel中创建和取消数据分组》Excel中的分组是一种通过添加层级结构将相邻行或列组织在一起的功能,当分组完成后,用户可以通过折叠或展开数据组来简化数据视图,这篇博客将介绍如何使... 目录引言使用工具python在Excel中创建行和列分组Python在Excel中创建嵌套分组Pyt

MySQL报错sql_mode=only_full_group_by的问题解决

《MySQL报错sql_mode=only_full_group_by的问题解决》本文主要介绍了MySQL报错sql_mode=only_full_group_by的问题解决,文中通过示例代码介绍的非... 目录报错信息DataGrip 报错还原Navicat 报错还原报错原因解决方案查看当前 sql mo

使用C#如何创建人名或其他物体随机分组

《使用C#如何创建人名或其他物体随机分组》文章描述了一个随机分配人员到多个团队的代码示例,包括将人员列表随机化并根据组数分配到不同组,最后按组号排序显示结果... 目录C#创建人名或其他物体随机分组此示例使用以下代码将人员分配到组代码首先将lstPeople ListBox总结C#创建人名或其他物体随机分组

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

matlab读取NC文件(含group)

matlab读取NC文件(含group): NC文件数据结构: 代码: % 打开 NetCDF 文件filename = 'your_file.nc'; % 替换为你的文件名% 使用 netcdf.open 函数打开文件ncid = netcdf.open(filename, 'NC_NOWRITE');% 查看文件中的组% 假设我们想读取名为 "group1" 的组groupName

Solr 使用Facet分组过程中与分词的矛盾解决办法

对于一般查询而言  ,  分词和存储都是必要的  .  比如  CPU  类型  ”Intel  酷睿  2  双核  P7570”,  拆分成  ”Intel”,”  酷睿  ”,”P7570”  这样一些关键字并分别索引  ,  可能提供更好的搜索体验  .  但是如果将  CPU  作为 Facet  字段  ,  最好不进行分词  .  这样就造成了矛盾  ,  解决方法

AI辅助编程里的 Atom Group 的概念和使用

背景 在我们实际的开发当中,一个需求往往会涉及到多个文件修改,而需求也往往有相似性。 举个例子,我经常需要在 auto-coder中需要添加命令行参数,通常是这样的: /coding 添加一个新的命令行参数 --chat_model 默认值为空 实际上这个需求涉及到以下文件列表: /Users/allwefantasy/projects/auto-coder/src/autocoder/auto

Java8特性:分组、提取字段、去重、过滤、差集、交集

总结下自己使用过的特性 将对象集合根据某个字段分组 //根据id分组Map<String, List<Bean>> newMap = successCf.stream().collect(Collectors.groupingBy(b -> b.getId().trim())); 获取对象集合里面的某个字段的集合 List<Bean> list = new ArrayList<>

group by 新体会

group by 分组语句中的 select 后面查询的东西,只能是 group by 中的字段或聚合函数,如果含有group by 中的没有的字段,sql 会报错。 表users   例子:  1.select count(1),sex from users group by sex; sql执行正确   2.select count(id),sex from users gr

HDU 1712 ACboy needs your help (分组背包)

OJ题目:click here~~ 题意分析:分组背包入门题。N个课程,最多可使用M天的时间。给出i课程用j天所获得的profit 。 求最多使用M天的最大profit。对课程i ,1--M天的profit 只能选一个,或者不选。也就是说有的课程不上也没有关系。明显的分组背包。 AC_CODE int x[101][101];int main(){int n , m;while(c