洛谷传送门

文章目录

  • 题目描述
  • 解析
  • 代码

题目描述

解析

利用倍增,设计dp慢慢敲即可。。。
注意距离累加在一起会爆int,需要ll
特判条件非常之复杂。。。
心力交瘁,就酱了

代码

#include <bits/stdc++.h>
using namespace std;
#define ll long long
typedef pair<ll,ll> pr;
const int N = 3e5 + 100;
int n,m;
struct node{int id,h;bool operator < (const node y)const{return h<y.h;}
}p[N];
int pos[N];
int l[N],r[N],h[N];
bool ok(int x){return x>=1&&x<=n;}
ll jl(int x,int y){return abs(p[x].h-p[y].h);}
struct node2{ll dist,id;bool operator < (const node2 y)const{if(dist!=y.dist) return dist<y.dist;else return h[id]<h[y.id];}
};
node2 fir[N],sec[N];
void del(int x){r[l[x]]=r[x];l[r[x]]=l[x];return;
}
int pl[N][30];
ll dis[3][N][30];
int x0;
void solve(){sort(p+1,p+1+n);for(int i=1;i<=n;i++) pos[p[i].id]=i;for(int i=1;i<=n;i++){l[i]=i-1;r[i]=i+1;}r[0]=1;l[n+1]=n;for(int i=1;i<=n;i++){int pl=pos[i];int l1=0,l2=0,r1=0,r2=0;int num=0;node2 coi[5];if(ok(l[pl])) l1=l[pl],coi[++num]=(node2){jl(pl,l1),p[l1].id};if(l1&&ok(l[l1])) l2=l[l1],coi[++num]=(node2){jl(pl,l2),p[l2].id};if(ok(r[pl])) r1=r[pl],coi[++num]=(node2){jl(pl,r1),p[r1].id};if(r1&&ok(r[r1])) r2=r[r1],coi[++num]=(node2){jl(pl,r2),p[r2].id};sort(coi+1,coi+1+num);if(num>=1) fir[i]=coi[1];if(num>=2) sec[i]=coi[2];del(pl);//printf("i=%d fir=%d sec=%d\n",i,fir[i].id,sec[i].id);}for(int i=1;i<=n;i++){if(sec[i].id) pl[i][0]=sec[i].id;else pl[i][0]=i;}for(int i=1;i<=n;i++){if(pl[i][0]!=i&&fir[pl[i][0]].id) pl[i][1]=fir[pl[i][0]].id;else pl[i][1]=pl[i][0];}for(int i=1;i<=n;i++){if(sec[i].id) dis[1][i][0]=sec[i].dist;else dis[1][i][0]=0;dis[2][i][0]=0;}for(int i=1;i<=n;i++){dis[1][i][1]=dis[1][i][0];if(pl[i][0]!=i&&fir[pl[i][0]].id)dis[2][i][1]=fir[pl[i][0]].dist;else dis[2][i][1]=0;}for(int k=2;(1<<k)<=n;k++){for(int i=1;i<=n;i++){pl[i][k]=pl[pl[i][k-1]][k-1];dis[1][i][k]=dis[1][i][k-1]+dis[1][pl[i][k-1]][k-1];dis[2][i][k]=dis[2][i][k-1]+dis[2][pl[i][k-1]][k-1];}}
}
pair<ll,ll> find(int st,int x){//  printf("ask: st=%d x=%d\n",st,x);ll disa=0,disb=0,tot=0;int ppl=st;for(int k=20;k>=0;k--){if((1<<k)>n) continue;ll suma=dis[1][ppl][k],sumb=dis[2][ppl][k];if(suma+sumb+tot>x) continue;tot+=suma+sumb;disa+=suma;disb+=sumb;ppl=pl[ppl][k];}
//  printf("  pl=%d disa=%d disb=%d\n",ppl,disa,disb);return make_pair(disa,disb);
}
void test(){for(int k=0;k<=3;k++){for(int i=1;i<=n;i++){printf("i=%d k=%d pl=%d dis1=%d dis2=%d\n",i,k,pl[i][k],dis[1][i][k],dis[2][i][k]);}}return ;
}
int main() {scanf("%lld",&n);for(int i=1;i<=n;i++){scanf("%lld",&p[i].h);h[i]=p[i].h;p[i].id=i;}solve();//test();scanf("%lld",&x0);double mn=2e16,temp;int anspl;for(int i=1;i<=n;i++){pr o=find(i,x0);//printf("st=%d disa=%d disb=%d\n",i,o.first,o.second);temp= o.second==0?2e15:1.0*o.first/o.second;if(temp<mn){mn=temp;anspl=i;}else if(temp==mn&&p[pos[anspl]].h<p[pos[i]].h) anspl=i;}printf("%lld\n",anspl);scanf("%lld",&m);int s,x;for(int i=1;i<=m;i++){scanf("%d%d",&s,&x);pr o=find(s,x);printf("%lld %lld\n",o.first,o.second);}return 0;
}
/*
10
4 5 6 1 2 3 7 8 9 10
7
10
1 7
2 7
3 7
4 7
5 7
6 7
7 7
8 7
9 7
10 7
*/

P1081 [NOIP2012 提高组] 开车旅行(倍增)(动态规划)相关推荐

  1. NOIP2012提高组 开车旅行 解题报告

    开车旅行 题目描述 样例输入 样例输出 70分算法 暴力预处理出对于每一个点他右边最近.次近的点的编号,对于每一个询问,暴力模拟开车过程即可. 100算法 和上面一样我们得预处理出每一个点最近.次近的 ...

  2. 洛谷P1083 [NOIP2012提高组Day2T2]借教室

    P1083 借教室 题目描述 在大学期间,经常需要租借教室.大到院系举办活动,小到学习小组自习讨论,都需要向学校申请借教室.教室的大小功能不同,借教室人的身份不同,借教室的手续也不一样. 面对海量租借 ...

  3. [NOIP2012提高组] CODEVS 1200 同余方程(扩展欧几里德算法)

    数论题..所有数论对我来说都很恶心..不想再说什么了.. ------------------------------------------------ #include<iostream&g ...

  4. [NOIP2012] 提高组 洛谷P1080 国王游戏

    题目描述 恰逢 H 国国庆,国王邀请 n 位大臣来玩一个有奖游戏.首先,他让每个大臣在左.右 手上面分别写下一个整数,国王自己也在左.右手上各写一个整数.然后,让这 n 位大臣排 成一排,国王站在队伍 ...

  5. P1091 [NOIP2004 提高组] 合唱队形(动态规划+LIS)

    P1091 [NOIP2004 提高组] 合唱队形 Part1:链接: 点我就送屠龙宝刀[doge] Part2:题目 Part3:思路 隔了这么久,屑人再次捡起了他的节操,洗了洗,然后开始续写他的苦 ...

  6. 【NOIP2012 提高组】 国王游戏

    题目: 恰逢 H 国国庆,国王邀请 n 位大臣来玩一个有奖游戏.首先,他让每个大臣在左.右手上面分别写下一个整数,国王自己也在左.右手上各写一个整数.然后,让这 n 位大臣排成一排,国王站在队伍的最前 ...

  7. 【NOIP2012提高组】开车旅行

    Description 现在有n个城市,每个城市有它的高度 Hi H_i,保证每个 Hi H_i互不相同.我们定义两个城市之间的距离 disi,j=|Hi−Hj| dis_{i,j}=|H_i-H_j ...

  8. NOIP2012 开车旅行 (倍增)

    题意:一行N个城市,有各自不同的海拔,定义两个城市之间的距离为海拔之差的绝对值,小a和小b轮流开车,开车方向从左往右,小a总是开到第二近的城市,小b开到最近的城市(如有两个城市和当前城市海拔之差相等, ...

  9. P1081 开车旅行 倍增 洛谷

    题目连接 题意 题目已经说的hin明确了. 题解 我们要求出从每个点出发,小A要走的城市和小B要走的城市. 我们把iii以后的所有点的海拔加入到set" role="present ...

最新文章

  1. 在wine里安装了IE6
  2. 王道408数据结构——第五章 树与二叉树
  3. 最拼爹的css属性:z-index失效情况记录
  4. TCP文件下载器(Python)
  5. 【C++】C++读取文本中的特定一列
  6. JS中的基本数据类型与引用数据类型
  7. 【Java从0到架构师】JDBC、Spring JDBC、JUnit
  8. QQ空间爬虫分享(2016年11月18日更新)
  9. Windows10+clion+opencv时报错0xC0000139和0xC0000135的解决方法之一
  10. Python.密码本生成
  11. android7.1修改默认休眠时间为1分钟
  12. 深圳随到随考,科目四随到随考,科三理论第二理论随到随考说明
  13. 使用 Microsoft RDC for Mac 在 Mac 和 Windows 间传文件
  14. 企业邮箱09年的十大新闻
  15. html箭头相关符号
  16. interrupt()方法理解和实例
  17. 实现用友U8+与旺店通ERP数据同步
  18. 营销学习思维导图模板
  19. c语言程序设计账单,个人账单管理系统数据结构.doc
  20. 【微信开发第四章】SpringBoot实现微信H5支付

热门文章

  1. java更新数据库错误就回滚_Java 中对数据库操作时的 回滚
  2. edge robert matlab,哪位熟悉matlab的大神路过瞄一眼哈
  3. c语言怎样表示运行时间,C语言运行时间
  4. linux系统故障实验,Linux常见系统故障排除
  5. java 根据客户端重定向_JavaWeb【1.4HttpServletResponse类、重定向】
  6. ibm台式计算机不能自动关机,IBM X3650 M3 不定时自动关机求大神
  7. 39. 组合总和020(思路+详解)
  8. C++ 学习之旅(2)——链接器Linker
  9. [C++11]lambda表达式语法
  10. [Java基础]自动装箱和拆箱