洛谷 P1081 开车旅行【双向链表+倍增】
倍增数组的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 开车旅行【双向链表+倍增】的更多相关文章
- 2018.11.04 洛谷P1081 开车旅行(倍增)
传送门 思路简单码量超凡? 感觉看完题大家应该都知道是倍增sbsbsb题了吧. 首先预处理出从每个点出发如果是AAA走到哪个点,如果是BBB走到哪个点. 然后利用刚刚预处理出的信息再预处理从每个点出发 ...
- 洛谷 P1081 开车旅行(70)
P1081 开车旅行 题目描述 小AA 和小BB 决定利用假期外出旅行,他们将想去的城市从 11到 NN 编号,且编号较小的城市在编号较大的城市的西边,已知各个城市的海拔高度互不相同,记城市 ii的海 ...
- 洛谷P1081 开车旅行
题目 双向链表+倍增+模拟. \(70pts\): 说白了此题的暴力就是细节较多的模拟题. 我们设离\(i\)城市最近的点的位置为\(B[i]\),第二近的位置为\(A[i]\).设\(A\)或\(B ...
- 洛谷 P1081 开车旅行 —— 倍增
题目:https://www.luogu.org/problemnew/show/P1081 真是倍增好题! 预处理:f[i][j] 表示从 i 点开始走 2^j 次 AB (A,B各走一次)到达的点 ...
- 洛谷P1081 开车旅行(倍增)
题意 题目链接 Sol 咕了一年的题解.. 并不算是很难,只是代码有点毒瘤 \(f[i][j]\)表示从\(i\)号节点出发走了\(2^j\)轮后总的距离 \(da[i][j]\)同理表示\(a\)的 ...
- [NOIP2012] 提高组 洛谷P1081 开车旅行
题目描述 小 A 和小 B 决定利用假期外出旅行,他们将想去的城市从 1 到 N 编号,且编号较小的 城市在编号较大的城市的西边,已知各个城市的海拔高度互不相同,记城市 i 的海拔高度为 Hi,城市 ...
- NOIP 2012 洛谷P1081 开车旅行
Description: 就是两个人开车,只能向东开.向东有n个城市,城市之间的距离为他们的高度差.A,B轮流开车,A喜欢到次近的城市,B喜欢到最近的城市.如果车子开到底了或者车子开的路程已经超过了限 ...
- 洛谷P1081——开车旅行
传送门:QAQQAQ 题意注意点: 1.是从前往后走,不能回头 2.小A小B轮流开,先小A开,而小A是到第二近的点(这点调试的时候查了好久) 3.若绝对值差相同海拔低的更近,而第一个询问若比值相同是海 ...
- 洛谷P1081 开车旅行70分
https://www.luogu.org/problem/show?pid=1081 太遗憾了明明写出来了,却把最小值初始值弄小了,从第二个点开始就不可能对了.70分! #include<io ...
随机推荐
- Python数据分析常用的库总结
Python之所以能够成为数据分析与挖掘领域的最佳语言,是有其独特的优势的.因为他有很多这个领域相关的库可以用,而且很好用,比如Numpy.SciPy.Matploglib.Pandas.Scikit ...
- POJ 1502 水 dij
题意:给N,表示N个节点. 给半个邻接矩阵,本身到本身的距离是0,边是双向的.当两个节点之间没有直接的边连接的时候,用x表示. 问从第一个节点到其他所有节点至少花费的时间. 这题唯一的处理是处理邻接矩 ...
- codeforces 875F(基环外向树)
题意 有一个左边m个点,右边n个点的二分图(n,m<=1e5),左边每个点向右边恰好连两条权值相同的边. 求这个二分图的最优匹配 分析 对于这种二选一问题,即左边的a连向右边的b和c,权值为d, ...
- springboot使用过程中遇到的问题
一.工具Intellij IDEA 二.基本问题 1.数据库语句 Caused by: java.lang.IllegalStateException: Cannot load driver clas ...
- Java时间戳转化为今天、昨天、明天(字符串格式)
原文:http://www.open-open.com/code/view/1435301895825 时间戳,相信大家一定都不陌生,服务器经常会传回来时间戳,需要我们对时间戳进行处理.各种麻烦不断, ...
- 【Nginx】ngx_event_core_module事件模块
功能:创建连接池,决定使用哪些事件驱动机制,以及初始化将要使用的事件模块 该模块定义了ngx_event_core_commands数组处理其感兴趣的7个配置项 ngx_event_conf_t为该模 ...
- Desert King (poj 2728 最优比率生成树 0-1分数规划)
Language: Default Desert King Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 22113 A ...
- office outlook 無法開啟 outlook 視窗
例如[無法啟動Microsoft Office Outlook.無法開啟Outlook 視窗.] 1.啟動 Outlook 安全模式outlook.exe /safe2.清除並重新產生目前設定檔的功能 ...
- MySQL存储结构的使用
前言 今天公司老大让我做一个MySQL的调研工作,是关于MySQL的存储结构的使用.这里我会通过3个样例来介绍一下MySQL中存储结构的使用过程,以及一些须要注意的点. 笔者环境 系统:Windows ...
- struts2 java.io.FileNotFoundException: http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd
xxx-validation.xml 文件里 java.io.FileNotFoundException: http://www.opensymphony.com/xwork/xwork-valid ...