传送门

思路简单码量超凡?

感觉看完题大家应该都知道是倍增sbsbsb题了吧。

首先预处理出从每个点出发如果是AAA走到哪个点,如果是BBB走到哪个点。

然后利用刚刚预处理出的信息再预处理从每个点出发AAA走2i2^i2i次的距离,BBB走2i2^i2i次的距离,A,BA,BA,B走2i2^i2i轮之后到了哪个点。

剩下的询问就跑倍增就行了。

代码:

  1. #include<bits/stdc++.h>
  2. #include<tr1/unordered_map>
  3. #define fi first
  4. #define se second
  5. using namespace std;
  6. inline int read(){
  7. int ans=0,w=1;
  8. char ch=getchar();
  9. while(!isdigit(ch)){if(ch=='-')w=-1;ch=getchar();}
  10. while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
  11. return ans*w;
  12. }
  13. typedef pair<int,int> pii;
  14. const int N=1e5+5;
  15. int Ans=0,ansa=0x3f3f3f3f,ansb=0,x0,n,m,h[N],st[N][21],disa[N][21],disb[N][21],nxta[N],nxtb[N];
  16. struct Node{
  17. int id,val;
  18. friend inline bool operator<(const Node&a,const Node&b){return a.val==b.val?h[a.id]<h[b.id]:a.val<b.val;}
  19. };
  20. inline void init(){
  21. set<pii>S;
  22. int tot=0;
  23. Node tmp[5];
  24. tot=0;
  25. for(int pos=n;pos;--pos){
  26. S.insert(pii(h[pos],pos));
  27. if(pos==n)continue;
  28. tot=0;
  29. set<pii>::iterator it=S.find(pii(h[pos],pos));
  30. if(it!=S.begin()){
  31. --it,tmp[++tot]=(Node){it->se,h[pos]-it->fi};
  32. if(it!=S.begin())--it,tmp[++tot]=(Node){it->se,h[pos]-it->fi},++it;
  33. ++it;
  34. }
  35. if((++it)!=S.end()){
  36. tmp[++tot]=(Node){it->se,it->fi-h[pos]};
  37. if((++it)!=S.end())tmp[++tot]=(Node){it->se,it->fi-h[pos]};
  38. }
  39. sort(tmp+1,tmp+tot+1);
  40. nxtb[pos]=tmp[1].id;
  41. if(tot^1)nxta[pos]=tmp[2].id;
  42. }
  43. for(int i=1;i<=n;++i){
  44. int p1=nxta[i],p2=nxtb[p1];
  45. disa[i][0]=p1?abs(h[p1]-h[i]):0,disb[i][0]=p2?abs(h[p1]-h[p2]):0,st[i][0]=p2;
  46. }
  47. for(int j=1;j<=20;++j)for(int i=1;i<=n;++i){
  48. st[i][j]=st[st[i][j-1]][j-1];
  49. disa[i][j]=disa[i][j-1]+disa[st[i][j-1]][j-1];
  50. disb[i][j]=disb[i][j-1]+disb[st[i][j-1]][j-1];
  51. }
  52. }
  53. inline pii solve(int s,int dis){
  54. pii ret=pii(0,0);
  55. for(int i=20;~i;--i)if(st[s][i]&&disa[s][i]+disb[s][i]<=dis)dis-=disa[s][i]+disb[s][i],ret.fi+=disa[s][i],ret.se+=disb[s][i],s=st[s][i];
  56. if(!nxta[s]||abs(h[nxta[s]]-h[s])>dis)return ret;
  57. return ret.fi+=abs(h[nxta[s]]-h[s]),ret;
  58. }
  59. int main(){
  60. n=read();
  61. for(int i=1;i<=n;++i)h[i]=read();
  62. init(),x0=read();
  63. pii ans;
  64. for(int i=1;i<=n;++i){
  65. pii res=solve(i,x0);
  66. if(!Ans||((long long)ansa*res.se>(long long)ansb*res.fi))ansa=res.fi,ansb=res.se,Ans=i;
  67. }
  68. printf("%d\n",Ans);
  69. for(int i=read(),x,s;i;--i)s=read(),x=read(),ans=solve(s,x),printf("%d %d\n",ans.fi,ans.se);
  70. return 0;
  71. }

2018.11.04 洛谷P1081 开车旅行(倍增)的更多相关文章

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

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

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

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

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

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

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

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

  5. NOIP 2012 洛谷P1081 开车旅行

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

  6. 2018.11.04 洛谷P2679 子串(线性dp)

    传送门 为什么前几年的noipnoipnoip总是出这种送分题啊? 这个直接线性dpdpdp不就完了吗? f[i][j][k][0/1]f[i][j][k][0/1]f[i][j][k][0/1]表示 ...

  7. 洛谷P1081 开车旅行70分

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

  8. 洛谷 P1081 开车旅行【双向链表+倍增】

    倍增数组的20和N写反了反复WAWAWA-- 注意到a和b在每个点上出发都会到一个指定的点,所以这样构成了两棵以n点为根的树 假设我们建出了这两棵树,对于第一问就可以枚举起点然后倍增的找出ab路径长度 ...

  9. 洛谷P1081 开车旅行

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

随机推荐

  1. 81. Search in Rotated Sorted Array II (Array; Divide-and-Conquer)

    Follow up for "Search in Rotated Sorted Array":What if duplicates are allowed? Would this ...

  2. f5冗余BIG-IP系统的安装

    1.设备服务群集 •一个系列的BIG-Ips彼此互相支持DSC •每一台BIG-IP 自己生成一个Device Object •不同设备的信息 •建立信任证书 •在local device上设置Dev ...

  3. 20165315 预备作业3 Linux安装及学习

    20165315 预备作业3 Linux安装及学习 一.在自己笔记本上安装Linux操作系统 因为对操作电脑的不熟悉,我在第一项任务上就花费了一定的时间,在安装过程有如下问题: 我的电脑是苹果公司的M ...

  4. 44-java断点调式dubug

    转自:https://www.cnblogs.com/mq0036/p/3780538.html Eclipse 的单步调试 1.设置断点在程序里面放置一个断点,也就是双击需要放置断点的程序左边的栏目 ...

  5. pycurl提示load dll failed 找不到注册程序

    原因:python虽然是2.7的 但有小版本区别 建议使用2.7.8

  6. 如何查看Firefox中保存的登录密码

    问:以前使用Firefox浏览器登录一个论坛,并且临时申请了一个账号,在使用Firefox登录时选择让它记住密码了,后来,我忘记了那个论坛的密码,但是可以使用Firefox直接登录.现在能不能查看密码 ...

  7. YII2中自定义用户认证模型,完成登陆和注册

    有些时候我们需要自已定义用户类,操作自已建的用户表,来完成登陆和注册功能. 用户表结构如下,当然可以根据自已的需要添加或删除: CREATE TABLE `tb_user` ( `id` int(11 ...

  8. php ActiveMQ的安装与使用

    一.ActiveMQ是什么?ActiveMQ是Apache出品,最流行的,能力强劲的开源消息总线.支持多种语言客户端(Java,C,C++,C#,Python,Ruby,Perl,PHP), 支持多种 ...

  9. 解决video标签在微信中强制全屏、微信全屏播放(Android和IOS)

    在video标签中加上代码: x5-playsinline="true" webkit-playsinline="true" playsinline=" ...

  10. JavaScript 中 如何判断一个元素是否在一个数组中

    <script type="text/javascript"> var arrList=['12','qw','q','v','d','t']; console.log ...