CodeForces 173E Camping Groups 离线线段树 树状数组
Camping Groups
题目连接:
http://codeforces.com/problemset/problem/173/E
Description
A club wants to take its members camping. In order to organize the event better the club directors decided to partition the members into several groups.
Club member i has a responsibility value ri and an age value ai. A group is a non-empty subset of club members with one member known as group leader. A group leader should be one of the most responsible members of the group (his responsibility value is not less than responsibility of any other group member) and his age absolute difference with any other group member should not exceed k.
Some club members are friends and want to be in the same group. They also like their group to be as large as possible. Now you should write a program that answers a series of questions like "What's the largest size of a group containing club member x and club member y?". It's possible for x or y to be the group leader.
Input
The first line contains two integers n and k (2 ≤ n ≤ 105, 0 ≤ k ≤ 109) — the number of club members and the age restriction for one group.
The next line contains integer numbers r1, r2, ..., rn (1 ≤ ri ≤ 109) separated by space: ri denotes the i-th club member's responsibility. In the same way there are integers a1, a2, ..., an (1 ≤ ai ≤ 109) in the third line: ai denotes the i-th club member's age.
The next line contains an integer q denoting the number of questions that you should answer (1 ≤ q ≤ 105). The next q lines describe the questions. Each line contains two space-separated integers xi and yi (1 ≤ xi, yi ≤ n, xi ≠ yi) — the indices of the club members that should end up in the same group.
Output
For each question print the maximum size of the group in a line. If making such a group is impossible print -1 instead.
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
Hint
题意
给你n个人,每个人都有两个属性点,ri和ai,表示这个人的领导值和年龄
然后可以让一个人当领导,他可以领导所有领导值小于等于他的人,年龄和他的之差不超过k的人
然后Q次询问
问你x,y所能够在的最大团队的大小是多少
题解:
离散化是显然的
首先,我们离线树状数组,按照领导值从小到大排序之后,年龄当成坐标,去维护每一个人当领导的时候能够领导多少个人
然后我们再把所有询问全部读入,把询问和每个人都扔到一个vector里面,按照领导值从大到小排序,这样显然先更新的点一定能够统领后面的人
然后再离线去维护询问就好了
代码
#include<bits/stdc++.h>
using namespace std;
struct node
{
int x,y,id;
int flag;
int ans;
}p[1300000],p2[1300000],p3[1300000];
int n,k;
vector<int> V;
map<int,int> H;
typedef int SgTreeDataType;
struct treenode
{
int L , R ;
SgTreeDataType sum , lazy;
};
struct Question
{
int l,r,lead,flag,ans;
};
vector<Question>T;
treenode tree[2300000];
inline void push_up(int o)
{
tree[o].sum = max(tree[2*o].sum , tree[2*o+1].sum);
}
inline void build_tree(int L , int R , int o)
{
tree[o].L = L , tree[o].R = R,tree[o].sum = tree[o].lazy = 0;
if (R > L)
{
int mid = (L+R) >> 1;
build_tree(L,mid,o*2);
build_tree(mid+1,R,o*2+1);
}
}
inline void updata(int QL,int QR,SgTreeDataType v,int o)
{
int L = tree[o].L , R = tree[o].R;
if (QL <= L && R <= QR) tree[o].sum = max(tree[o].sum,v);
else
{
int mid = (L+R)>>1;
if (QL <= mid) updata(QL,QR,v,o*2);
if (QR > mid) updata(QL,QR,v,o*2+1);
push_up(o);
}
}
inline SgTreeDataType query(int QL,int QR,int o)
{
int L = tree[o].L , R = tree[o].R;
if (QL <= L && R <= QR) return tree[o].sum;
else
{
int mid = (L+R)>>1;
SgTreeDataType res = 0;
if (QL <= mid) res = max(res,query(QL,QR,2*o));
if (QR > mid) res = max(res,query(QL,QR,2*o+1));
push_up(o);
return res;
}
}
struct Bit
{
vector<int> a;
int sz;
void init(int n)
{
sz=n;
for(int i=1;i<=n+5;i++)
a.push_back(0);
}
int lowbit(int x)
{
return x&(-x);
}
int query(int x)
{
if(x==0)return 0;
int ans = 0;
for(;x;x-=lowbit(x))ans+=a[x];
return ans;
}
void updata(int x,int v)
{
if(x==0)return;
for(;x<sz;x+=lowbit(x))
a[x]+=v;
}
}bit;
bool cmp(node a,node b)
{
if(a.x==b.x)return a.flag>b.flag;
return a.x<b.x;
}
bool cmp2(Question a,Question b)
{
if(a.lead == b.lead)
return a.flag<b.flag;
return a.lead>b.lead;
}
int ans[1300000];
int main()
{
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
scanf("%d",&p[i].x);
for(int i=1;i<=n;i++)
{
scanf("%d",&p[i].y);
V.push_back(p[i].y);
V.push_back(p[i].y-k);
V.push_back(p[i].y+k);
p[i].id=i;
p[i].flag=1;
}
sort(V.begin(),V.end());
V.erase(unique(V.begin(),V.end()),V.end());
for(int i=0;i<V.size();i++)
H[V[i]]=i+1;
for(int i=1;i<=n;i++)
p2[i]=p[i];
for(int i=1;i<=n;i++)
{
p2[i+n]=p[i];
p2[i+n].flag=-1;
}
sort(p2+1,p2+2*n+1,cmp);
bit.init(10*n);
for(int i=1;i<=2*n;i++)
{
if(p2[i].flag==1)
bit.updata(H[p2[i].y],1);
else
{
int sum = bit.query(H[p2[i].y+k])-bit.query(H[p2[i].y-k]-1);
p[p2[i].id].ans=sum;
}
}
for(int i=1;i<=n;i++)
{
Question now;
now.l = p[i].y;
now.r = p[i].y;
now.lead = p[i].x;
now.ans = p[i].ans;
now.flag = 0;
T.push_back(now);
}
int q;scanf("%d",&q);
for(int i=1;i<=q;i++)
{
int x,y;
scanf("%d%d",&x,&y);
if(p[x].y>p[y].y)swap(x,y);
Question now;
now.l = p[y].y-k;
now.r = p[x].y+k;
now.lead = max(p[x].x,p[y].x);
now.ans = 0;
now.flag = i;
T.push_back(now);
}
sort(T.begin(),T.end(),cmp2);
build_tree(1,5*n+5*q,1);
for(int i=0;i<T.size();i++)
{
if(T[i].flag==0)
updata(H[T[i].l],H[T[i].r],T[i].ans,1);
else
{
if(T[i].l>T[i].r)ans[T[i].flag]=-1;
else{
int ans1 = query(H[T[i].l],H[T[i].r],1);
ans[T[i].flag] = ans1;
}
}
}
for(int i=1;i<=q;i++)
{
if(ans[i]<2)
printf("-1\n");
else
printf("%d\n",ans[i]);
}
}
CodeForces 173E Camping Groups 离线线段树 树状数组的更多相关文章
- CodeForces - 1087F:Rock-Paper-Scissors Champion(set&数状数组)
n players are going to play a rock-paper-scissors tournament. As you probably know, in a one-on-one ...
- CodeForces -163E :e-Government (AC自动机+DFS序+树状数组)
The best programmers of Embezzland compete to develop a part of the project called "e-Governmen ...
- HDU 4638 Group (线段树 | 树状数组 + 离线处理)
Group Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submi ...
- Educational Codeforces Round 10 D. Nested Segments 离线树状数组 离散化
D. Nested Segments 题目连接: http://www.codeforces.com/contest/652/problem/D Description You are given n ...
- HDU 3874 Necklace (树状数组 | 线段树 的离线处理)
Necklace Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total S ...
- Codeforces Round #365 (Div. 2) D. Mishka and Interesting sum (离线树状数组+前缀xor)
题目链接:http://codeforces.com/contest/703/problem/D 给你n个数,m次查询,每次查询问你l到r之间出现偶数次的数字xor和是多少. 我们可以先预处理前缀和X ...
- Codeforces Gym 100114 H. Milestones 离线树状数组
H. Milestones Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100114 Descripti ...
- hdu 4288 离线线段树+间隔求和
Coder Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Su ...
- bzoj2333 离线 + 线段树
https://www.lydsy.com/JudgeOnline/problem.php?id=2333 有N个节点,标号从1到N,这N个节点一开始相互不连通.第i个节点的初始权值为a[i],接下来 ...
随机推荐
- YII Framework学习教程-YII的国际化
一个web应用,发布到互联网,就是面向全球用户.用户在世界的各个角落都可以访问到你的web应用,当然要看你的网站和不和谐,不和谐的web应用在和谐社会是不让你访问的. YII提供了国际化的支持,可以让 ...
- 被投资人“送”入看守所 z
http://news.cnblogs.com/n/506969/ 拜读了[[畅言]读<被投资人“送”入看守所>一文有感]一文有感,很想跟作者探讨几句.虽然他的看法很有理性,但站在一个刑案 ...
- loadrunner之C语言编程
一.常量定义 #define COUNT 100 //定义全局常量#define SALARY 4000 Action(){ int total; total = C ...
- latex公式中的空格如何表示
两个quad空格 a \qquad b 两个m的宽度 quad空格 a \quad b 一个m的宽度 大空格 a\ b 1/3m宽度 中等空格 a\;b 2/7m宽度 小空格 a\,b 1/6m宽度 ...
- mybatis源码学习: 动态代理的应用(慢慢改)
动态代理概述 在学spring的时候知道使用动态代理实现aop,入门的列子:需要计算所有方法的调用时间.可以每个方法开始和结束都获取当前时间咋办呢.类似这样: long current=system. ...
- xargs 简单功能
之所以能用到这个命令,关键是由于很多命令不支持|管道来传递参数,而日常工作中有有这个必要,所以就有了xargs命令,例如: find /sbin -perm +700 |ls -l 这个命 ...
- [POJ] #1006# Biorhythms : 最小公倍数/同余问题
一. 题目 Biorhythms Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 127263 Accepted: 403 ...
- RxCache 的代码分析,含缓存时间duration的在代码中改变的自己实现的机制
当应用进程创建 RxCache 的实例后,会给应用进程返回一个 rxcache实例及一个 ProxyProvider,代码如下: CacheProviders providers = new RxCa ...
- Spark生态系统BDAS
目前,Spark已经发展成为包含众多子项目的大数据计算平台. 伯克利将Spark的整个生态系统称为伯克利数据分析栈(BDAS). 其核心框架是Spark,同时BDAS涵盖支持结构化数据SQL查询与分析 ...
- Codeforces Round #292 (Div. 1) B. Drazil and Tiles (类似拓扑)
题目链接:http://codeforces.com/problemset/problem/516/B 一个n*m的方格,'*'不能填.给你很多个1*2的尖括号,问你是否能用唯一填法填满方格. 类似t ...