倍增数组的20和N写反了反复WAWAWA……

注意到a和b在每个点上出发都会到一个指定的点,所以这样构成了两棵以n点为根的树

假设我们建出了这两棵树,对于第一问就可以枚举起点然后倍增的找出ab路径长度的比值,第二问同理,这里倍增的时候注意是先跳a再跳b,所以同一个点b的倍增数组要从a在这个点的的父亲开始,然后位置倍增数组也是这样,这样位置倍增相当于跳完a再跳b

然后这个树怎么建呢,开一个双向链表,表内按h排升序,因为一个点的最大次大值一定在比它小的值中最大的两个和比它大的值中最小的两个之中,所以直接用链表查即可,然后查完一个点就把它删掉,因为这个点不能用来更新id比他大的点

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=100005;
int n,m,rl[N],ff[N],gg[N];
long long h[N],f[20][N],g[20][N],fa[20][N],da,db;
struct qwe
{
int id,l,r;
long long h;
}a[N];
bool cmp(const qwe &a,const qwe &b)
{
return a.h<b.h;
}
int read()
{
int r=0,f=1;
char p=getchar();
while(p>'9'||p<'0')
{
if(p=='-')
f=-1;
p=getchar();
}
while(p>='0'&&p<='9')
{
r=r*10+p-48;
p=getchar();
}
return r*f;
}
void wk(int w,long long x)
{
da=0,db=0;
for(int i=17;i>=0;i--)
if(fa[i][w]!=0&&da+db+f[i][w]+g[i][w]<=x)
da+=f[i][w],db+=g[i][w],w=fa[i][w];
if(ff[w]!=0&&da+db+f[0][w]<=x)
da+=f[0][w];
}
int main()
{
n=read();
for(int i=1;i<=n;i++)
h[i]=a[i].h=read(),a[i].id=i;
sort(a+1,a+1+n,cmp);
for(int i=1;i<=n;i++)
rl[a[i].id]=i,a[i].l=i-1,a[i].r=i+1;
a[0].h=1e10,a[n+1].h=1e10;
for(int i=1;i<=n;i++)
{
int ll=a[a[rl[i]].l].l,l=a[rl[i]].l,r=a[rl[i]].r,rr=a[a[rl[i]].r].r;
if(!l)
gg[i]=a[r].id,ff[i]=a[rr].id;
else if(r==n+1)
gg[i]=a[l].id,ff[i]=a[ll].id;
else if(abs(h[i]-a[l].h)<=abs(h[i]-a[r].h))
gg[i]=a[l].id,ff[i]=(abs(h[i]-a[ll].h)<=abs(h[i]-a[r].h))?a[ll].id:a[r].id;
else
gg[i]=a[r].id,ff[i]=(abs(h[i]-a[l].h)<=abs(h[i]-a[rr].h))?a[l].id:a[rr].id;
a[a[rl[i]].l].r=a[rl[i]].r,a[a[rl[i]].r].l=a[rl[i]].l;
// cerr<<" "<<ff[i]<<" "<<gg[i]<<endl;
}
for(int i=1;i<=n;i++)
{
fa[0][i]=gg[ff[i]];
f[0][i]=abs(h[ff[i]]-h[i]);
g[0][i]=abs(h[fa[0][i]]-h[ff[i]]);
}
for(int i=1;i<=17;i++)
for(int j=1;j<=n;j++)
fa[i][j]=fa[i-1][fa[i-1][j]],f[i][j]=f[i-1][j]+f[i-1][fa[i-1][j]],g[i][j]=g[i-1][j]+g[i-1][fa[i-1][j]];
long long x0=read(),w=0;
double ans=1e18;
for(int c=1;c<=n;c++)
{
wk(c,x0);
if(db!=0&&1.0*da/db<ans)
{
ans=1.0*da/db;
w=c;
}
}
printf("%d\n",w);
m=read();
while(m--)
{
long long s=read(),x=read();
wk(s,x);
printf("%lld %lld\n",da,db);
}
return 0;
}

洛谷 P1081 开车旅行【双向链表+倍增】的更多相关文章

  1. 2018.11.04 洛谷P1081 开车旅行(倍增)

    传送门 思路简单码量超凡? 感觉看完题大家应该都知道是倍增sbsbsb题了吧. 首先预处理出从每个点出发如果是AAA走到哪个点,如果是BBB走到哪个点. 然后利用刚刚预处理出的信息再预处理从每个点出发 ...

  2. 洛谷 P1081 开车旅行(70)

    P1081 开车旅行 题目描述 小AA 和小BB 决定利用假期外出旅行,他们将想去的城市从 11到 NN 编号,且编号较小的城市在编号较大的城市的西边,已知各个城市的海拔高度互不相同,记城市 ii的海 ...

  3. 洛谷P1081 开车旅行

    题目 双向链表+倍增+模拟. \(70pts\): 说白了此题的暴力就是细节较多的模拟题. 我们设离\(i\)城市最近的点的位置为\(B[i]\),第二近的位置为\(A[i]\).设\(A\)或\(B ...

  4. 洛谷 P1081 开车旅行 —— 倍增

    题目:https://www.luogu.org/problemnew/show/P1081 真是倍增好题! 预处理:f[i][j] 表示从 i 点开始走 2^j 次 AB (A,B各走一次)到达的点 ...

  5. 洛谷P1081 开车旅行(倍增)

    题意 题目链接 Sol 咕了一年的题解.. 并不算是很难,只是代码有点毒瘤 \(f[i][j]\)表示从\(i\)号节点出发走了\(2^j\)轮后总的距离 \(da[i][j]\)同理表示\(a\)的 ...

  6. [NOIP2012] 提高组 洛谷P1081 开车旅行

    题目描述 小 A 和小 B 决定利用假期外出旅行,他们将想去的城市从 1 到 N 编号,且编号较小的 城市在编号较大的城市的西边,已知各个城市的海拔高度互不相同,记城市 i 的海拔高度为 Hi,城市 ...

  7. NOIP 2012 洛谷P1081 开车旅行

    Description: 就是两个人开车,只能向东开.向东有n个城市,城市之间的距离为他们的高度差.A,B轮流开车,A喜欢到次近的城市,B喜欢到最近的城市.如果车子开到底了或者车子开的路程已经超过了限 ...

  8. 洛谷P1081——开车旅行

    传送门:QAQQAQ 题意注意点: 1.是从前往后走,不能回头 2.小A小B轮流开,先小A开,而小A是到第二近的点(这点调试的时候查了好久) 3.若绝对值差相同海拔低的更近,而第一个询问若比值相同是海 ...

  9. 洛谷P1081 开车旅行70分

    https://www.luogu.org/problem/show?pid=1081 太遗憾了明明写出来了,却把最小值初始值弄小了,从第二个点开始就不可能对了.70分! #include<io ...

随机推荐

  1. Springmvc 前台传递参数到后台需要数据绑定

    我们知道,当提交表单时,controller会把表单元素注入到command类里,但是系统注入的只能是基本类型,如int,char,String.但当我们在command类里需要复杂类型,如Integ ...

  2. ArcGIS Engine 中的多线程使用

    转自原文ArcGIS Engine 中的多线程使用 一直都想写写AE中多线程的使用,但一直苦于没有时间,终于在中秋假期闲了下来.呵呵,闲话不说了,进入正题! 大家都了解到ArcGIS中处理大数据量时速 ...

  3. Shiro note

    我们需要实现Realms的Authentication 和 Authorization.其中 Authentication 是用来验证用户身份,Authorization 是授权访问控制,用于对用户进 ...

  4. 从头开始学Android之(一)——— Android架构

    从事Android开发已经两年多了,最近项目上特别清闲,刚开始时在闲暇的时候都不知道干嘛,整天混日子.有一天突然有个以前同学找到我,说要我帮忙做一个Android的需求,就是在后台截屏(涉及到服务以及 ...

  5. GO语言 --socket.io

    socket.io是对websocket的封装以及扩展, 可以跨平台使用, 具体可看官网.. GO语言实现: package main import ( "github.com/googol ...

  6. Android之怎样实现滑动页面切换【Fragment】

    Fragment 页面切换不能滑动 所以对于listview 能够加入的左右滑动事件 .不会有冲突比如(QQ的好友列表的删除)  Fragment 和viewpager 的差别  Viewpager ...

  7. PHP的类中的常量,静态变量的问题。

    自己在写一个小型的 angularJS 库的时候,觉得 javascript 中的很多概念有点像是PHP中的概念. 像类常量, 类中的静态变量(类的静态变量是类的所有实例都共享的),这些概念虽然在 j ...

  8. Ajax系列之四:问题总结

    1.最经典的就是ie下的缓存问题了.  假设使用的是get.那么在ie下出现缓存问题.导致代码仅仅运行一次. 解决的方法就是加时间戳或者随机数,使url变为唯一,这样就不会出现ie  下的缓存问题了, ...

  9. SonarQube---在具体项目中的使用

    一.简介 SonarQube(简称Sonar)是管理代码质量的开放平台,它可以快速地对代码质量进行分析,并给出合理的解决方案,提高管理效率,保证代码质量. Sonar官网,文档 Sonar Scann ...

  10. soapUI系列之—-03 Groovy脚本常用方法2

    ------Groovy脚本常用方法 1.解析Json数据脚本 //groovy读取json的方式很简单,re.body.businessinfo.c2rate读取c2rate对应的值 import ...