题目描述
一条道路上,位置点用整数A表示。
当A=0时,有一个王宫。当A>0,就是离王宫的东边有A米,当A<0,就是离王宫的西边有A米。
道路上,有N个住宅从西向东用1-N来标号。每个住宅有一个人。住宅只会存在于偶数整数点。
该国国王认为,国民体质下降,必须要多运动,于是下命令所有人都必须出门散步。所有的国民,一秒钟可以走1米。每个国民各自向东或者向西走。这些方向你是知道的。命令发出后所有人同时离开家门开始散步。
然而该国的国民个都很健谈,如果在散步途中两个人相遇,就会停下来交谈。正在走路的人碰到已经停下来的人(重合)也会停下来交谈。一但停下来,就会聊到天昏地暗,忘记了散步。
现在命令已经发出了T秒,该国有Q个重要人物,国王希望能够把握他们的位置。你能帮他解答吗?
输入输出格式
输入格式:
第一行是3个整数,N,T,Q
接下来N行,每行两个整数Ai,Ri。Ai是家的坐标,如果Ri是1,那么会向东走,如果是2,向西。数据保证Ai是升序排序,而且不会有两个人初始位置重合。
接下来Q行,每行一个整数,表示国王关心的重要人物。
输出格式:
Q行,每行一个整数,表示这个人的坐标。
输入输出样例
6 6 4
-10 1
-6 2
-4 1
2 1
6 2
18 2
2
3
4
6
-8
2
4
12
说明
20%数据 N<=100,T<=10000
另外20%数据 N<=5000
另外20%数据 从最西边数起连续的若干国民全部往东,剩下的全部往西
100%数据 Ai为偶数,|Ai|<=10^18,|T|<=10^18,1<=Q<=N<=100000.
只想到部分分
官方题解:
为什么数据范围这么奇怪?因为这个范围已经剧透了。
我们先考虑“从西边数连续的人全部往东,剩下的全部往西”这个。
我们会发现,他们最后都会集中在一个点上。哪个点?就是中间的那对面对面的中间点。我们只要判断时间内,人能不能走到这个点停下来。于是20分get。
100分呢?我们是不是可以吧所有人分成若干组,然后每一组分别计算啊?
例如样例,我们将
(
认为往东,)
往西。他们最终会停在|
的地方。第一组 第二组
( | ) ( ( | ) )
-10 -8 -6 -4 2 4 6 18于是我们就很清楚了。
那最左边的人向左,最右边的人向右怎么办呢?那就让他走呗,特判一下,反正永远也停不下来。
想到那20%了,原来扫描然后分组就可以了......................
//
// main.cpp
// luogu10r2.2
//
// Created by Candy on 10/15/16.
// Copyright © 2016 Candy. All rights reserved.
// #include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N=1e5+;
inline ll read(){
char c=getchar();ll x=,f=;
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
}
ll n,t,Q,a[N],d[N],q[N],ans[N];
void cal(int l,int r){
if(l==r) a[l]+=d[l]*t;
else if(d[l]==-||d[r]==)
for(int i=l;i<=r;i++) a[i]+=d[i]*t;
else{
int pos=l;
while(d[pos+]==) pos++;
ll mid=(a[pos]+a[pos+])/;
for(int i=l;i<=r;i++){
ll tmp=a[i]+t*d[i];
if((a[i]<=mid&&tmp>=mid)||(a[i]>=mid&&tmp<=mid)) a[i]=mid;
else a[i]=tmp;
}
}
}
int main(int argc, const char * argv[]) {
n=read();t=read();Q=read();
for(int i=;i<=n;i++) {
a[i]=read(),d[i]=read();
if(d[i]==) d[i]=-;
}
for(int i=;i<=Q;i++) q[i]=read(); int l=,dir=;
for(int i=;i<=n;i++){
if(d[i]==&&dir==-){
cal(l,i-);
l=i;
dir=;
}
dir=d[i];
}
if(l<=n) cal(l,n);
for(int i=;i<=Q;i++) printf("%lld\n",a[q[i]]);
return ;
}