博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
洛谷P3407 散步[分组]
阅读量:5775 次
发布时间:2019-06-18

本文共 2398 字,大约阅读时间需要 7 分钟。

题目描述

一条道路上,位置点用整数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行,每行一个整数,表示这个人的坐标。

 

输入输出样例

输入样例#1:
6 6 4-10 1-6 2-4 12 16 218 22346
输出样例#1:
-82412

说明

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 
#include
#include
#include
using namespace std;typedef long long ll;const int N=1e5+5;inline ll read(){ char c=getchar();ll x=0,f=1; while(c<'0'||c>'9'){
if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';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]==-1||d[r]==1) for(int i=l;i<=r;i++) a[i]+=d[i]*t; else{ int pos=l; while(d[pos+1]==1) pos++; ll mid=(a[pos]+a[pos+1])/2; 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=1;i<=n;i++) { a[i]=read(),d[i]=read(); if(d[i]==2) d[i]=-1; } for(int i=1;i<=Q;i++) q[i]=read(); int l=1,dir=1; for(int i=1;i<=n;i++){ if(d[i]==1&&dir==-1){ cal(l,i-1); l=i; dir=1; } dir=d[i]; } if(l<=n) cal(l,n); for(int i=1;i<=Q;i++) printf("%lld\n",a[q[i]]); return 0;}

 

转载地址:http://irhux.baihongyu.com/

你可能感兴趣的文章
经济利益与民族国家支持已成为主要恶意活动驱动主体
查看>>
虚拟应用快速恢复是部署混合云的关键所在
查看>>
菜鸟网络与数据服务商Youredi签署合作协议
查看>>
基于业务的Web自动化测试工具—Sahi
查看>>
如何管理自己的测试团队
查看>>
深度挖掘手机数据,伦敦广告公司Ogury 获1500万美元 B 轮融资
查看>>
“大数据”催生新型全产业链
查看>>
《C语言编程魔法书:基于C11标准》——3.3 本章小结
查看>>
《GDAL源码剖析与开发指南》一一1.7 SWIG编译
查看>>
Linux 内核自防护项目
查看>>
《MATLAB R2012a超级学习手册》一1.6 使用MATLAB R2012a帮助系统
查看>>
Grsecurity 稳定版补丁只提供给赞助商
查看>>
《推荐系统:技术、评估及高效算法》一第1章 概述
查看>>
开源项目为什么都爱把动物作为品牌 Logo ?
查看>>
Objective-C中的属性机制
查看>>
Oracle 日常应用笔记
查看>>
【RAC】集群验证工具cluvfy 实践之二
查看>>
myeclipse svn 修改用户名和密码
查看>>
Found duplicate PV 7UXOslmOGAme9YkHi7cbT6pajucbdppY: using /dev/sdq not /dev/sda
查看>>
福建SEO:根据跳出率和退出率分析用户体验
查看>>