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 ...
随机推荐
- Appium+python自动化2-启动百度app
一.前言 上一章节环境已经搭建好了,接下来就是需要启动APP,如何启动app呢?首先要获取包名,然后获取launcherActivity.获取这两个关键东西的方法很多,这里就不一一多说,小伙伴们可以各 ...
- [转]github详细教程
GitHub详解 GitHub 是一个共享虚拟主机服务,用于存放使用Git版本控制的软件代码和内容项目.它由GitHub公司(曾称Logical Awesome)的开发者Chris Wanstrath ...
- PHP20-challenge10
今天咩,说一个关于php的题目,里面主要主要牵扯到截断的知识点,这让我多了解了一些机制. 1.截断 截断,简单来说就是16进制的00,代表空.其实,那些输出语句函数就是凭借语句后面这个我们看不 ...
- jquey中json字符串与json的转换(转)
<!doctype html> <html> <head> <meta charset="utf-8"> <script sr ...
- [leetcode]300. Longest Increasing Subsequence最长递增子序列
Given an unsorted array of integers, find the length of longest increasing subsequence. Example: Inp ...
- 基于java NIO 的服务端与客户端代码
在对java NIO selector 与 Buffer Channel 有一定的了解之后,我们进行编写java nio 实现的 客户端与服务端例子: 服务端: public class NIOC ...
- elasticsearch命令
如果安装了x-pack插件,需要验证 curl -u username:passwd 1.查看所有index curl -XGET localhost:/_cat/indices?v 2.清理所有in ...
- 2018.3.15 css课外小知识
1, 如果手动写动画, 最小的时间间隔是多久 为什么 多数显示器默认频率是60Hz 1s刷新60次 所以理论最小是1/60*1000ms=16.7ms 2. display:inline-bloc ...
- 解决Eclipse添加新server时无法选择Tomcat7的问题
在Eclipse中创建了一个Web工程后,需要将该工程部署到Tomcat中进行发布.有时就会遇到在New Server对话框中选择了Tomcat 6/7后却无法单击“Next”按钮的问题,如下图所示: ...
- kalman滤波(一)---对各参数的理解
一.引言 1.卡尔曼滤波中的真实值,测量值,预测值,估计值怎么区分?他的5条公式是其核心内容,结合现代的计算机,其实卡尔曼的程序相当的简单,只要你理解了他的那5条公式. 用一个简单的小例子:假设我们要 ...