【GDOI2018模拟8.7】的士碰撞
来源:互联网 发布:知荣制衣 联系方式 编辑:程序博客网 时间:2024/04/28 03:14
Description
n辆车在一条数轴上,车的编号为1到n。编号为i的车坐标为a[i],初始方向为dir[i](左或右),初始位置两两不同。每辆车每个时刻行走距离为1。两辆车相碰时,会调转方向,继续行走,掉头不消耗时间。现在车子开始朝其方向行驶,同一个坐标允许有多辆车。现在有q个询问,给出 t,i,询问过了t时刻后,编号为i的车的坐标的绝对值。
Input
输入文件名为collision.in。
首先输入n,q 。
接下来n行,每行两个整数a[i],dir[i],若dir[i]=0,表示车子向左行走,若dir[i]=1,表示车子向右行走。
接下来 q行,每行两个整数t,i ,询问时刻 t时编号为i 的车的坐标。
Output
输出文件名为collision.out。
对于每个询问,输出一个整数,代表编号为i的车的坐标。
Sample Input
输入1:
5 5
1 1
4 1
2 0
7 1
11 0
5 1
10 2
7 3
8 4
20 5
输入2:
20 15
31116973 1
721410312 0
152891538 1
55434456 0
903968 1
34492580 0
97565125 0
78559065 1
191708700 0
335941230 0
526621966 1
168159348 1
457798506 1
160026937 1
76511872 1
247171016 1
48722268 0
159552820 0
701333640 0
434868520 1
143857480 13
821356724 11
132436670 1
20249229 11
504666 16
138701034 19
339607872 1
184664000 13
80827802 15
625365533 5
668115287 6
93821572 7
175176488 5
438184710 1
71279702 12
Data Constraint
Solution
这题真的太妙了
两个车碰撞,相当于两个车互相穿过,编号互换
而且无论怎么碰撞,车辆之间的相对位置是不会改变的
比如说1号车在2号车左边
那么2号车无论怎么撞都不可能跑到1号车左边
那么t时刻后每辆车的位置就是a[i]+/-t
这时给出要求的车的编号,我们知道这个编号的车初始时的排名,设为y
那么答案就是所有车中排名为y的那辆车的坐标
这个二分坐标mid
那么就是要求有多少车在这个坐标前面
将车往左和往右的分为两种
在往左的车中二分求出初始位置为mid+t之前的有多少
往右的车中二分求出初始位置为mid-t之前有多少
就可以得出答案了
PS
二分有个upper_bound和lower_bound
upper_bound是求出>k的第一个位置
lower_bound是求出>=k的第一个位置
这题中第二个二分一个简单方法就是upper_bound出位置之后-1
Code
#include<cstring>#include<algorithm>#include<cmath>#define fo(i,a,b) for(int i=a;i<=b;i++)#define N 101000#define INF 10000000000ll#define ll long longusing namespace std;ll n,m,b[N],c[N],ans[N],t1=0,t2=0,d[N];struct node{ ll x,y,z;}a[N];bool cnt(node x,node y){return x.x<y.x;}int main(){ freopen("collision.in","r",stdin); freopen("collision.out","w",stdout); scanf("%d%d",&n,&m); fo(i,1,n) scanf("%lld%lld",&a[i].x,&a[i].y),a[i].x+=INF,a[i].z=i; sort(a+1,a+n+1,cnt); fo(i,1,n) { d[a[i].z]=i; if(a[i].y==0) c[++t2]=a[i].x; else b[++t1]=a[i].x; } b[++t1]=INF+INF+INF+2; c[++t2]=INF+INF+INF+2; fo(i,1,m) { ll x,y;scanf("%lld%d",&x,&y); ll l=0,r=INF+INF+INF+INF; while(l+1<r) { ll mid=(l+r)/2,ans=0; ll z=upper_bound(b+1,b+t1+1,mid-x)-b-1; z=z+upper_bound(c+1,c+t2+1,mid+x)-c-1; if(z<d[y]) l=mid;else r=mid; } printf("%lld\n",abs(r-INF)); }}
- 【GDOI2018模拟8.7】的士碰撞
- 【jzoj5238】【GDOI2018模拟8.7】【的士碰撞】
- 【JZOJ5238】【GDOI2018模拟8.7】的士碰撞
- JZOJ5238【GDOI模拟】的士碰撞
- GDOI2016模拟8.18的士
- 【GDOI2018模拟8.7】最长公共子序列
- 【GDOI2018模拟8.7】图的异或
- 【GDOI2018模拟7.6】吃干饭
- 【GDOI2018模拟7.9】期末考试
- 【GDOI2018模拟7.8】质数
- 【GDOI2018模拟7.8】矩阵
- 【GDOI2018模拟7.10】B
- 【GDOI2018模拟7.10】C
- 【GDOI2018模拟7.10】B
- 【GDOI2018模拟7.10】C
- 【GDOI2018模拟7.12】B
- 【GDOI2018模拟7.12】C
- 【GDOI2018模拟7.12】A
- 5-1 列出连通集 (25分)
- Xamarin.Forms 用户界面——控件——Text——Label
- CentOS MongoDB安装与使用
- Matlab2014a for MAC安装Piotr's Image & Video Matlab Toolbox
- Android 单元测试 Mockito使用详解
- 【GDOI2018模拟8.7】的士碰撞
- 使用Java Rest Client操作Elasticsearch
- spring mvc 使用注意事项
- 简易的省市二级联动
- mysql数据查询优化。
- iOS自适应手机语言的国家&国旗列表
- Myeclipse的tomcat配置(详细配图)
- string
- 从入门到入门-Spring Boot-Controller