倍增数组的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. Codeforces 659D Bicycle Race【计算几何】

    题目链接: http://codeforces.com/contest/659/problem/D 题意: 若干条直线围城的湖,给定直线的端点,判断多少个转点会有危险?(危险是指直走的的话会掉进水里) ...

  2. git批量删除本地分支及远程分支

    1.批量删除本地分支 git branch |grep 'branchName' |xargs git branch -D git branch   查看本地分支 | grep 'branchName ...

  3. 洛谷——P3353 在你窗外闪耀的星星

    P3353 在你窗外闪耀的星星 题目描述 飞逝的的时光不会模糊我对你的记忆.难以相信从我第一次见到你以来已经过去了3年.我仍然还生动地记得,3年前,在美丽的集美中学,从我看到你微笑着走出教室,你将头向 ...

  4. [Poj2411]Mondriaan's Dream(状压dp)(插头dp)

    Mondriaan's Dream Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 18096   Accepted: 103 ...

  5. 一个Tomcat最多支持多少用户的并发?

    ,也就是说同时支持 另外,在 Java 中每开启一个线程需要耗用 1MB 的 JVM 内存空间用于作为线程栈之用.Tomcat的最大并发数是可以配置的,实际运用中,最大并发数与硬件性能和CPU数量都有 ...

  6. 转:Linux中的内存管理

    前一段时间看了<深入理解Linux内核>对其中的内存管理部分花了不少时间,但是还是有很多问题不是很清楚,最近又花了一些时间复习了一下,在这里记录下自己的理解和对Linux中内存管理的一些看 ...

  7. Puppet基于Master/Agent模式实现LNMP平台部署

    前言 随着IT行业的迅猛发展,传统的运维方式靠大量人力比较吃力,运维人员面对日益增长的服务器和运维工作,不得不把很多重复的.繁琐的工作利用自动化处理.前期我们介绍了运维自动化工具ansible的简单应 ...

  8. Qt 调用 Java 方法笔记

    Qt 调用 Java 方法笔记 假设遇到相似的错误: error: undefined reference to '_jstring* QAndroidJniObject::callStaticMet ...

  9. 使用RNN解决句子对匹配问题的常见网络结构

    /* 版权声明:能够随意转载,转载时请标明文章原始出处和作者信息 .*/ author: 张俊林 除了序列标注问题外,句子对匹配(Sentence Pair Matching)问题也是NLP中非经常见 ...

  10. jsp引用JSTL核心标签库

    一.引用JSTL 1.  JSTL的引入可以让JSP代码中<%%>等代码消失掉,再结合EL表达式,会更加方便以及美观. 2.  各套框架(还没有学习,比如struts,SpringMVC等 ...