【JZOJ 3854】分组
来源:互联网 发布:淘宝新店引流量 编辑:程序博客网 时间:2024/06/15 12:14
Description
Bsny所在的精灵社区有n个居民,每个居民有一定的地位和年龄,ri表示第i个人的地位,ai表示第i个人的年龄。
最近社区里要举行活动,要求几个人分成一个小组,小组中必须要有一个队长,要成为队长有这样的条件:
1、队长在小组中的地位应该是最高的(可以并列第一);
2、小组中其他成员的年龄和队长的年龄差距不能超过K。
有些人想和自己亲密的人组在同一个小组,同时希望所在的小组人越多越好。比如x和y想在同一个小组,同时希望它们所在的小组人越多越好,当然,它们也必须选一个符合上述要求的队长,那么问你,要同时包含x和y的小组,最多可以组多少人?
Solution
先把每个人按地位排序,这样就可以预处理出每个人做组长可以领导多少人,(这里我用了树状数组)
再把输入的问题也按两个人中地位最大的排序,离线处理,
对于每个人可以确认一个年龄区间,要保证组长一定在这个年龄范围内,
用一个指针指向每一组人,按全部人的地位从大到小循环,看一下指向的组两人的最大地位是否大于当前的人,是则结算当前的人答案,指针后移,最后加上当前人的影响,(鄙人的语文辣鸡,大家可以看看代码理解一下)
这个可以用线段树,
复杂度:
Code
#include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#define fo(i,a,b) for(int i=a;i<=b;i++)#define fod(i,a,b) for(int i=a;i>=b;i--)#define NX(x) ((x)&(-(x)))using namespace std;const int N = 1e5+500;int read(int &n){ char ch=' ';int q=0,w=1; for(;(ch!='-')&&((ch<'0')||(ch>'9'));ch=getchar()); if(ch=='-')w=-1,ch=getchar(); for(;ch>='0' && ch<='9';ch=getchar())q=q*10+ch-48;n=q*w;return n;}int n,m,m1;int zx[N],ans[N];struct qqww{ int rk,a,i,f,zx;}a[N];int A[N];int F[N];struct qwqw{ int x,y,i;}sc[N];int b[4*N];bool PX(qqww q,qqww w){return q.rk<w.rk || q.rk==w.rk&&q.a<w.a;}bool PPX(qwqw q,qwqw w){return a[q.x].rk<a[w.x].rk;}int SUM(int q){ int ans=0; for(;q>0;q-=NX(q))ans+=F[q]; return ans;}void ADD(int q){for(;q<=m1;q+=NX(q))F[q]++;}int find(int l,int r,int e,int l1,int r1){ if(l==l1&&r==r1)return b[e]; int t=(l+r)>>1; if(r1<=t)return find(l,t,e*2,l1,r1); else if(t<l1)return find(t+1,r,e*2+1,l1,r1); else return max(find(l,t,e*2,l1,t),find(t+1,r,e*2+1,t+1,r1));}void change(int l,int r,int e,int l1,int l2){ if(l==r){b[e]=max(b[e],l2);return;} int t=(l+r)>>1; if(l1<=t)change(l,t,e*2,l1,l2); else change(t+1,r,e*2+1,l1,l2); b[e]=max(b[e*2],b[e*2+1]);}int main(){ int q,w,_; read(n),read(m); fo(i,1,n)read(a[i].rk),a[i].i=i; fo(i,1,n)A[i]=read(a[i].a); sort(a+1,a+1+n,PX); fo(i,1,n)zx[a[i].i]=i; sort(A+1,A+1+n); m1=1; fo(i,2,n)if(A[i]!=A[i-1])A[++m1]=A[i]; int t=1; fo(i,1,n) { a[i].zx=lower_bound(A+1,A+1+m1,a[i].a)-A; ADD(a[i].zx); if(a[i].rk!=a[i+1].rk) while(t<=i) { q=lower_bound(A+1,A+1+m1,a[t].a-m)-A; w=upper_bound(A+1,A+1+m1,a[t].a+m)-A-1; a[t].f=SUM(w)-SUM(q-1),t++; } } // fo(i,1,n)printf("%d ",a[i].f);printf("\n"); read(_); int __=_; fo(i,1,_) { read(q),read(w);q=zx[q],w=zx[w]; if(a[q].rk<a[w].rk)swap(q,w); sc[i].x=q,sc[i].y=w;sc[i].i=i; } sort(sc+1,sc+1+_,PPX); fod(i,n,0) { for(;a[i].rk<a[sc[_].x].rk;_--) { if(a[sc[_].x].a<a[sc[_].y].a)swap(sc[_].x,sc[_].y); q=lower_bound(A+1,A+1+m1,a[sc[_].x].a-m)-A;q=max(1,q); w=upper_bound(A+1,A+1+m1,a[sc[_].y].a+m)-A-1; if(q<=w)ans[sc[_].i]=find(1,n,1,q,w); } change(1,n,1,a[i].zx,a[i].f); } fo(i,1,__)if(ans[i])printf("%d\n",ans[i]);else printf("-1\n"); return 0;}
0 0
- 【JZOJ 3854】分组
- 【JZOJ 3854】 分组
- 分组
- 分组
- 分组.
- 分组
- 分组
- 分组
- 分组
- 分组
- 分组
- 分组
- [JZOJ 3424] 粉刷匠 && [JZOJ 4254] 集体照
- 分组与分组函数
- [JZOJ 1280]最大匹配
- [JZOJ 1281]旅行
- [1282 JZOJ]资源勘探
- [JZOJ 1283]排序统计
- UVA12100 Printer Queue 【双端队列】
- Android学习笔记之蓝牙通信...
- SVG(可缩放矢量图形)绘制工具Method Draw
- docker原理及基本概念
- 问题四十二:怎么用ray tracing画任意圆环片段
- 【JZOJ 3854】分组
- 程序员面试金典——解题总结: 9.12测试 12.3如何测试国际象棋程序中的移动方法?
- Total size of serialized results of 20 tasks (1088.8 MB) is bigger than spark.driver.maxResultSize (
- java 木马开发(1)
- 企业微信开发者回调模式
- 远程linux系统
- 新版QQ斗地主记牌器
- Python零基础入门十三之异常
- iOS 加载webView进度条