【noip2012】开车旅行
题意:
给n个点的海拔h[i](不同点海拔不同) 两点的距离为abs(h[i]-h[j]) 有a、b两人轮流开车(只能往下标大的地方开) a每次会开到里当前点第二近的点 b每次会开到离当前点最近的点(距离相同h小的近) 给定x 如果a或b继续开距离和会大于x就不继续开。
求两个问题
1、给定x=x0求从哪点开始开能使a开的距离:b开的距离最小 不值相同取海拔高的
2、给出m个询问 每个询问给定x1、y1 求从x1开始走且x=y1 a能走的距离和b能走的距离
题解:
不难发现(其实我一开始没发现 看了题解才知道TAT)从固定某点i走到的后若干个点和x没关系
我们可以预处理出从i点走j个点 a、b走的距离 由于数据略大 可以用倍增做 move[i][j] 表示i开始走2^j步 a、b走的距离
由于n比较大 不能n^2直接算离某点最近和第二进的点是谁
可以先把所有的h[i]拿来排序 建立双向链表 显然i点的最近点一定是双向链表中i的前驱或后继 而次近点则还可能是前驱的前驱或后继的后继 每次求完将该点从双向链表中删除 这样就能o(n) 求出最近和次近点了
然后我们就可以倍增轻松求出i开始走 且a、b走的距离<=x a、b分别走了多远了(第二个问题解决)
对于第一个问题 也很简单 直接枚从哪个点开始走算ans就完了
代码:
#include <cstdio>
#include <algorithm>
typedef long long ll;
using std::sort;
const ll N=;
struct info{
ll t,ma,mb,bo;
info(const ll a=,const ll b=,const ll c=,const ll d=):
t(a),ma(b),mb(c),bo(d){}
}move[N][][],save;
struct inli{
ll t,pr,ne;
inli(const ll a=,const ll b=,const ll c=):
t(a),pr(b),ne(c){}
}line[N];
struct inim{
ll t,s;
inim(const ll a=,const ll b=):
t(a),s(b){}
}im[N];
inline bool cmp(inim x,inim y){ return x.t<y.t; }
ll h[N],sp[N],n,m,x0,ans;
void makeline(){
for (ll i=;i<=n;i++){
line[i].t=im[i].s;
if (i>) line[i].pr=i-;
if (i<n) line[i].ne=i+;
}
}
void makeres(ll &res1,ll &res2,ll t,ll a1){
if (!a1) return;
if (res1== || abs(h[t]-h[a1])<abs(h[t]-h[res1]) ||
(abs(h[t]-h[a1])==abs(h[t]-h[res1]) && h[a1]<h[res1])) res2=res1,res1=a1;
else if (res2== || abs(h[t]-h[a1])<abs(h[t]-h[res2]) ||
(abs(h[t]-h[a1])==abs(h[t]-h[res2]) && h[a1]<h[res2])) res2=a1;
}
inim getmove(ll t,ll a1,ll a2,ll a3,ll a4){
ll res1=,res2=;
if (t==)
t=;
makeres(res1,res2,t,line[a1].t);
makeres(res1,res2,t,line[a2].t);
makeres(res1,res2,t,line[a3].t);
makeres(res1,res2,t,line[a4].t);
if (!res1) return inim(res2,res1);
return inim(res1,res2);
}
void makemove0(){
for (ll i=;i<n;i++){
if (i==)
i=;
inim x=getmove(i,line[sp[i]].pr,line[sp[i]].pr ? line[line[sp[i]].pr].pr : ,
line[sp[i]].ne,line[sp[i]].ne ? line[line[sp[i]].ne].ne : );
move[i][][].t=x.t;
move[i][][].ma=abs(h[i]-h[x.t]);
move[i][][].bo=;
if (x.s){
move[i][][].t=x.s;
move[i][][].mb=abs(h[i]-h[x.s]);
move[i][][].bo=;
}
line[line[sp[i]].pr].ne=line[sp[i]].ne;
line[line[sp[i]].ne].pr=line[sp[i]].pr;
}
}
void makemove(){
makemove0();
for (ll i=n;i;i--)
for (ll k=;k<=;k++){
if (i==)
i=;
for (ll j=;move[move[i][j-][k].t][j-][move[i][j-][k].bo].t;j++){
info x=move[move[i][j-][k].t][j-][move[i][j-][k].bo];
move[i][j][k].t=x.t;
move[i][j][k].bo=x.bo;
move[i][j][k].ma=move[i][j-][k].ma+x.ma;
move[i][j][k].mb=move[i][j-][k].mb+x.mb;
}
}
}
info getans(ll x,ll y){
info res=info(x,,,);
for (;y>=move[res.t][][res.bo].ma+move[res.t][][res.bo].mb && move[res.t][][res.bo].t;){
ll i=,st=res.t,sb=res.bo;
while (y>=move[st][i][sb].ma+move[st][i][sb].mb && move[st][i][sb].t) ++i;
--i;
y-=move[st][i][sb].ma+move[st][i][sb].mb;
res.t=move[st][i][sb].t;
res.bo=move[st][i][sb].bo;
res.ma+=move[st][i][sb].ma;
res.mb+=move[st][i][sb].mb;
}
return res;
}
bool check(info x,ll y){
if (!ans) return ;
if (!x.ma){
if (save.ma) return ;
else return (h[y]>h[ans]);
}
if (!save.mb) return ;
if (save.ma*x.mb<save.mb*x.ma || (save.ma*x.mb==save.mb*x.ma && h[y]>h[ans])) return ;
else return ;
}
int main(){
freopen("drive.in","r",stdin);
freopen("drive.out","w",stdout);
scanf("%I64d",&n);
for (ll i=;i<=n;i++){
scanf("%I64d",&h[i]);
im[i]=inim(h[i],i);
}
sort(im+,im+n+,cmp);
for (ll i=;i<=n;i++) sp[im[i].s]=i;
makeline();
makemove();
scanf("%I64d",&x0);
for (ll i=;i<=n;i++){
info x=getans(i,x0);
if (check(x,i)) save=x,ans=i;
}
printf("%I64d\n",ans);
scanf("%I64d",&m);
ll x,y;
for (ll i=;i<=m;i++){
if (i==)
i=;
scanf("%I64d%I64d",&x,&y);
info xx=getans(x,y);
printf("%I64d %I64d\n",xx.mb,xx.ma);
}
fclose(stdin);
fclose(stdout);
}
【noip2012】开车旅行的更多相关文章
- Cogs 1264. [NOIP2012] 开车旅行(70分 暴力)
		
1264. [NOIP2012] 开车旅行 ★★☆ 输入文件:drive.in 输出文件:drive.out 简单对比时间限制:2 s 内存限制:128 MB [题目描述] 小A 和小 ...
 - P1081 [NOIP2012]开车旅行[倍增]
		
P1081 开车旅行 题面较为啰嗦.大概概括:一个数列,只能从一个点向后走,两种方案:A.走到和自己差的绝对值次小的点B.走到和自己差的绝对值最小点:花费为此差绝对值:若干询问从规定点向后最多花 ...
 - noip2012开车旅行 题解
		
题目大意: 给出n个排成一行的城市,每个城市有一个不同的海拔.定义两个城市间的距离等于他们的高度差的绝对值,且绝对值相等的时候海拔低的距离近.有两个人轮流开车,从左往右走.A每次都选最近的,B每次都选 ...
 - NOIP2012开车旅行  【倍增】
		
题目 小 A 和小 B 决定利用假期外出旅行,他们将想去的城市从 1 到 N 编号,且编号较小的城市在编号较大的城市的西边,已知各个城市的海拔高度互不相同,记城市 i 的海拔高度为Hi,城市 i 和城 ...
 - Luogu 1081 [NOIP2012] 开车旅行
		
感谢$LOJ$的数据让我调掉此题. 这道题的难点真的是预处理啊…… 首先我们预处理出小$A$和小$B$在每一个城市的时候会走向哪一个城市$ga_i$和$gb_i$,我们有链表和平衡树可以解决这个问题( ...
 - noip2012 开车旅行
		
此题100分的解法就是先预处理出每个点的下一个点之后倍增就好了.其实并没有太大难度. pbihao用双向链表写过了此题.在本地上我treap狂操他,but在rqnoj上,我依靠反复提交才A掉此题(最后 ...
 - Luogu1081 NOIP2012 开车旅行 倍增
		
题目传送门 为什么NOIP的题目都这么长qwq 话说2012的D1T3和D2T3都是大火题啊qwq 预处理神题 对于这种跳跳跳的题目考虑使用倍增优化枚举.先预处理某个点之后距离最小和次小的城市,然后倍 ...
 - luogu1081 [NOIp2012]开车旅行 (STL::multiset+倍增)
		
先用不管什么方法求出来从每个点出发,A走到哪.B走到哪(我写了一个很沙雕的STL) 然后把每个点拆成两个点,分别表示A从这里出发和B从这里出发,然后连边是要A连到B.B连到A.边长就是这次走的路径长度 ...
 - 洛谷1081 (NOIp2012) 开车旅行——倍增预处理
		
题目:https://www.luogu.org/problemnew/show/P1081 预处理从每个点开始a能走多少.b能走多少.可以像dp一样从后往前推. 但有X的限制.所以该数组可以变成倍增 ...
 - Luogu 1081 【NOIP2012】开车旅行 (链表,倍增)
		
Luogu 1081 [NOIP2012]开车旅行 (链表,倍增) Description 小A 和小B决定利用假期外出旅行,他们将想去的城市从1到N 编号,且编号较小的城市在编号较大的城市的西边,已 ...
 
随机推荐
- unity3d与eclipse集成开发android应用
			
原地址:http://blog.csdn.net/armoonwei/article/details/7032537 Unity as a Library Once you have eclipse ...
 - 注入攻击-SQL注入和代码注入
			
注入攻击 OWASP将注入攻击和跨站脚本攻击(XSS)列入网络应用程序十大常见安全风险.实际上,它们会一起出现,因为 XSS 攻击依赖于注入攻击的成功.虽然这是最明显的组合关系,但是注入攻击带来的不仅 ...
 - Spring MVC Checkbox And Checkboxes Example
			
In Spring MVC, <form:checkbox /> is used to render a HTML checkbox field, the checkbox values ...
 - Nagios监控部署(转)
			
转自 http://kyhack.blog.51cto.com/490370/213355 ky.blog 一.nagios简介 nagios是一款用于系统和网络监控的应用程序,它可以在 ...
 - 发现一个可以在线运行JS代码的网站
			
平时可以在这里玩 http://jsbin.com/
 - hbase总结:如何监控region的性能
			
转载:http://ju.outofmemory.cn/entry/50064 随着大数据表格应用的驱动,我们的HBase集群越来越大,然而由于机器.网络以及HBase内部的一些不确定性的bug,使得 ...
 - codeforces #313 div1 C
			
同BZOJ 3782 上学路线 QAQ 还比那个简单一点 把坐标(1,1)-(n,m)平移成(0,0)-(n-1,m-1) 设dp[i]表示从(1,1)出发第一次经过障碍且到达第i个障碍的方案数 首先 ...
 - [itint5]支持删除的后继查询
			
http://www.itint5.com/oj/#49 这一题一开始想到是用HashSet+链表来做,链表记录prev和next.这样也可以,后来看到都是连续的整数,而且交流了一下觉得可以用类似并查 ...
 - Linux 套接字编程中的 5 个隐患
			
http://www.ibm.com/developerworks/cn/linux/l-sockpit/ 在 4.2 BSD UNIX® 操作系统中首次引入,Sockets API 现在是任何操作系 ...
 - [ASP.NET MVC] 利用动态注入HTML的方式来设计复杂页面
			
原文:[ASP.NET MVC] 利用动态注入HTML的方式来设计复杂页面 随着最终用户对用户体验需求的不断提高,实际上我们很多情况下已经在按照桌面应用的标准来设计Web应用,甚至很多Web页面本身就 ...