2018.11.04 洛谷P1081 开车旅行(倍增)
传送门
思路简单码量超凡?
感觉看完题大家应该都知道是倍增sbsbsb题了吧。
首先预处理出从每个点出发如果是AAA走到哪个点,如果是BBB走到哪个点。
然后利用刚刚预处理出的信息再预处理从每个点出发AAA走2i2^i2i次的距离,BBB走2i2^i2i次的距离,A,BA,BA,B走2i2^i2i轮之后到了哪个点。
剩下的询问就跑倍增就行了。
代码:
#include<bits/stdc++.h>
#include<tr1/unordered_map>
#define fi first
#define se second
using namespace std;
inline int read(){
int ans=0,w=1;
char ch=getchar();
while(!isdigit(ch)){if(ch=='-')w=-1;ch=getchar();}
while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
return ans*w;
}
typedef pair<int,int> pii;
const int N=1e5+5;
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];
struct Node{
int id,val;
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;}
};
inline void init(){
set<pii>S;
int tot=0;
Node tmp[5];
tot=0;
for(int pos=n;pos;--pos){
S.insert(pii(h[pos],pos));
if(pos==n)continue;
tot=0;
set<pii>::iterator it=S.find(pii(h[pos],pos));
if(it!=S.begin()){
--it,tmp[++tot]=(Node){it->se,h[pos]-it->fi};
if(it!=S.begin())--it,tmp[++tot]=(Node){it->se,h[pos]-it->fi},++it;
++it;
}
if((++it)!=S.end()){
tmp[++tot]=(Node){it->se,it->fi-h[pos]};
if((++it)!=S.end())tmp[++tot]=(Node){it->se,it->fi-h[pos]};
}
sort(tmp+1,tmp+tot+1);
nxtb[pos]=tmp[1].id;
if(tot^1)nxta[pos]=tmp[2].id;
}
for(int i=1;i<=n;++i){
int p1=nxta[i],p2=nxtb[p1];
disa[i][0]=p1?abs(h[p1]-h[i]):0,disb[i][0]=p2?abs(h[p1]-h[p2]):0,st[i][0]=p2;
}
for(int j=1;j<=20;++j)for(int i=1;i<=n;++i){
st[i][j]=st[st[i][j-1]][j-1];
disa[i][j]=disa[i][j-1]+disa[st[i][j-1]][j-1];
disb[i][j]=disb[i][j-1]+disb[st[i][j-1]][j-1];
}
}
inline pii solve(int s,int dis){
pii ret=pii(0,0);
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];
if(!nxta[s]||abs(h[nxta[s]]-h[s])>dis)return ret;
return ret.fi+=abs(h[nxta[s]]-h[s]),ret;
}
int main(){
n=read();
for(int i=1;i<=n;++i)h[i]=read();
init(),x0=read();
pii ans;
for(int i=1;i<=n;++i){
pii res=solve(i,x0);
if(!Ans||((long long)ansa*res.se>(long long)ansb*res.fi))ansa=res.fi,ansb=res.se,Ans=i;
}
printf("%d\n",Ans);
for(int i=read(),x,s;i;--i)s=read(),x=read(),ans=solve(s,x),printf("%d %d\n",ans.fi,ans.se);
return 0;
}
2018.11.04 洛谷P1081 开车旅行(倍增)的更多相关文章
- 洛谷 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\)的 ...
- 洛谷 P1081 开车旅行(70)
P1081 开车旅行 题目描述 小AA 和小BB 决定利用假期外出旅行,他们将想去的城市从 11到 NN 编号,且编号较小的城市在编号较大的城市的西边,已知各个城市的海拔高度互不相同,记城市 ii的海 ...
- [NOIP2012] 提高组 洛谷P1081 开车旅行
题目描述 小 A 和小 B 决定利用假期外出旅行,他们将想去的城市从 1 到 N 编号,且编号较小的 城市在编号较大的城市的西边,已知各个城市的海拔高度互不相同,记城市 i 的海拔高度为 Hi,城市 ...
- NOIP 2012 洛谷P1081 开车旅行
Description: 就是两个人开车,只能向东开.向东有n个城市,城市之间的距离为他们的高度差.A,B轮流开车,A喜欢到次近的城市,B喜欢到最近的城市.如果车子开到底了或者车子开的路程已经超过了限 ...
- 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]表示 ...
- 洛谷P1081 开车旅行70分
https://www.luogu.org/problem/show?pid=1081 太遗憾了明明写出来了,却把最小值初始值弄小了,从第二个点开始就不可能对了.70分! #include<io ...
- 洛谷 P1081 开车旅行【双向链表+倍增】
倍增数组的20和N写反了反复WAWAWA-- 注意到a和b在每个点上出发都会到一个指定的点,所以这样构成了两棵以n点为根的树 假设我们建出了这两棵树,对于第一问就可以枚举起点然后倍增的找出ab路径长度 ...
- 洛谷P1081 开车旅行
题目 双向链表+倍增+模拟. \(70pts\): 说白了此题的暴力就是细节较多的模拟题. 我们设离\(i\)城市最近的点的位置为\(B[i]\),第二近的位置为\(A[i]\).设\(A\)或\(B ...
随机推荐
- 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 ...
- f5冗余BIG-IP系统的安装
1.设备服务群集 •一个系列的BIG-Ips彼此互相支持DSC •每一台BIG-IP 自己生成一个Device Object •不同设备的信息 •建立信任证书 •在local device上设置Dev ...
- 20165315 预备作业3 Linux安装及学习
20165315 预备作业3 Linux安装及学习 一.在自己笔记本上安装Linux操作系统 因为对操作电脑的不熟悉,我在第一项任务上就花费了一定的时间,在安装过程有如下问题: 我的电脑是苹果公司的M ...
- 44-java断点调式dubug
转自:https://www.cnblogs.com/mq0036/p/3780538.html Eclipse 的单步调试 1.设置断点在程序里面放置一个断点,也就是双击需要放置断点的程序左边的栏目 ...
- pycurl提示load dll failed 找不到注册程序
原因:python虽然是2.7的 但有小版本区别 建议使用2.7.8
- 如何查看Firefox中保存的登录密码
问:以前使用Firefox浏览器登录一个论坛,并且临时申请了一个账号,在使用Firefox登录时选择让它记住密码了,后来,我忘记了那个论坛的密码,但是可以使用Firefox直接登录.现在能不能查看密码 ...
- YII2中自定义用户认证模型,完成登陆和注册
有些时候我们需要自已定义用户类,操作自已建的用户表,来完成登陆和注册功能. 用户表结构如下,当然可以根据自已的需要添加或删除: CREATE TABLE `tb_user` ( `id` int(11 ...
- php ActiveMQ的安装与使用
一.ActiveMQ是什么?ActiveMQ是Apache出品,最流行的,能力强劲的开源消息总线.支持多种语言客户端(Java,C,C++,C#,Python,Ruby,Perl,PHP), 支持多种 ...
- 解决video标签在微信中强制全屏、微信全屏播放(Android和IOS)
在video标签中加上代码: x5-playsinline="true" webkit-playsinline="true" playsinline=" ...
- JavaScript 中 如何判断一个元素是否在一个数组中
<script type="text/javascript"> var arrList=['12','qw','q','v','d','t']; console.log ...