luogu1081 [NOIp2012]开车旅行 (STL::multiset+倍增)
先用不管什么方法求出来从每个点出发,A走到哪、B走到哪(我写了一个很沙雕的STL)
然后把每个点拆成两个点,分别表示A从这里出发和B从这里出发,然后连边是要A连到B、B连到A、边长就是这次走的路径长度
为了方便,把不能继续走的点连到一个假节点1上(不连应该也无所谓)
然后我们预处理倍增,但要把A走的距离和B走的距离分开来算
之后就每次往上跳找第一个不能走的地方,然后算一算答案就行了
(整数除整数别忘了先换成double或者乘个1.0.............)
#include<bits/stdc++.h>
#define pa pair<ll,int>
#define lowb(x) ((x)&(-(x)))
#define REP(i,n0,n) for(i=n0;i<=n;i++)
#define PER(i,n0,n) for(i=n;i>=n0;i--)
#define MAX(a,b) ((a>b)?a:b)
#define MIN(a,b) ((a<b)?a:b)
#define CLR(a,x) memset(a,x,sizeof(a))
#define rei register int
using namespace std;
typedef long long ll;
const int maxn=1e5+,logn=;
const ll inf=1e16; inline ll rd(){
ll x=;char c=getchar();int neg=;
while(c<''||c>''){if(c=='-') neg=-;c=getchar();}
while(c>=''&&c<='') x=x*+c-'',c=getchar();
return x*neg;
} int N,M,fa[maxn<<][logn];
ll h[maxn],dis1[maxn<<][logn],dis2[maxn<<][logn];
multiset<pa > st;
bool flag[maxn<<]; void getfa(int x){
flag[x]=;
if(fa[x][]&&!flag[fa[x][]]) getfa(fa[x][]);
for(int i=;fa[x][i-]&&fa[fa[x][i-]][i-];i++){
fa[x][i]=fa[fa[x][i-]][i-];
dis1[x][i]=dis1[x][i-]+dis1[fa[x][i-]][i-];
dis2[x][i]=dis2[x][i-]+dis2[fa[x][i-]][i-];
}
}
void getdis(ll &d1,ll &d2,int x,ll bnd){
d1=d2=;
for(int i=;i>=;i--){
if(fa[x][i]&&dis1[x][i]+dis2[x][i]<=bnd){
bnd-=dis1[x][i]+dis2[x][i];
d1+=dis1[x][i],d2+=dis2[x][i];
x=fa[x][i];
}
}
} int main(){
// freopen("1081.in","r",stdin);
rei i,j,k;
N=rd();
for(i=;i<=N;i++) h[i]=rd();
st.insert(make_pair(inf,));
for(i=N;i;i--){
multiset<pa>::iterator it=st.lower_bound(make_pair(h[i],));
ll mi=inf;int ma=;
if(it->first!=inf)
mi=it->first-h[i],ma=it->second;
if(it!=st.begin()){
it--;
if(h[i]-it->first<=mi) mi=h[i]-it->first,ma=it->second;
}
fa[i<<|][]=ma?(ma<<):;
dis2[i<<|][]=mi; ll mi2=inf;int ma2=;
if(mi!=inf){
it=st.lower_bound(make_pair(h[i]+mi,));
if(it->first!=inf&&it->first==h[i]+mi&&it->second!=ma){
mi2=mi,ma2=it->second;
}else{
if(it->first!=inf&&it->first-h[i]==mi) it++;
if(it->first!=inf&&it->first-h[i]>mi)
mi2=it->first-h[i],ma2=it->second;
it=st.lower_bound(make_pair(h[i]-mi,));
if(it!=st.begin()){
it--;
if(h[i]-it->first>mi&&h[i]-it->first<=mi2)
mi2=h[i]-it->first,ma2=it->second;
}
}
} fa[i<<][]=ma2?(ma2<<|):;
dis1[i<<][]=mi2;
st.insert(make_pair(h[i],i));
// printf("%d %d %lld %d %lld\n",i,fa[i<<1|1][0],mi,fa[i<<1][0],mi2);
}
// for(i=1;i<=(N<<1|1);i++) printf("%d %d\n",i,fa[i][0]);
for(i=;i<=(N<<|);i++) if(!flag[i]) getfa(i);
int x0=rd();
double mm=inf;int mi=;h[]=-inf;
for(i=;i<=N;i++){
ll d1=,d2=;
getdis(d1,d2,i<<,x0);
if(d2==&&mm==inf&&h[mi]<h[i]) mi=i;
else if(d2!=){
double r=1.0*d1/d2;
if(r<mm||(r==mm&&h[mi]<h[i])) mm=r,mi=i;
}
}
printf("%d\n",mi); M=rd();
for(i=;i<=M;i++){
ll d1=,d2=;
int a=rd();ll b=rd();
getdis(d1,d2,a<<,b);
printf("%lld %lld\n",d1,d2);
}
return ;
}
luogu1081 [NOIp2012]开车旅行 (STL::multiset+倍增)的更多相关文章
- Luogu1081 NOIP2012 开车旅行 倍增
题目传送门 为什么NOIP的题目都这么长qwq 话说2012的D1T3和D2T3都是大火题啊qwq 预处理神题 对于这种跳跳跳的题目考虑使用倍增优化枚举.先预处理某个点之后距离最小和次小的城市,然后倍 ...
- Cogs 1264. [NOIP2012] 开车旅行(70分 暴力)
1264. [NOIP2012] 开车旅行 ★★☆ 输入文件:drive.in 输出文件:drive.out 简单对比时间限制:2 s 内存限制:128 MB [题目描述] 小A 和小 ...
- P1081 [NOIP2012]开车旅行[倍增]
P1081 开车旅行 题面较为啰嗦.大概概括:一个数列,只能从一个点向后走,两种方案:A.走到和自己差的绝对值次小的点B.走到和自己差的绝对值最小点:花费为此差绝对值:若干询问从规定点向后最多花 ...
- NOIP2012开车旅行 【倍增】
题目 小 A 和小 B 决定利用假期外出旅行,他们将想去的城市从 1 到 N 编号,且编号较小的城市在编号较大的城市的西边,已知各个城市的海拔高度互不相同,记城市 i 的海拔高度为Hi,城市 i 和城 ...
- luogu1081 开车旅行2012 D1T3 (倍增,set,O2)
题目描述 小 A 和小 B 决定利用假期外出旅行,他们将想去的城市从 1 到 N 编号,且编号较小的城市在编号较大的城市的西边,已知各个城市的海拔高度互不相同,记城市 i 的海拔高度为Hi,城市 i ...
- 洛谷1081 (NOIp2012) 开车旅行——倍增预处理
题目:https://www.luogu.org/problemnew/show/P1081 预处理从每个点开始a能走多少.b能走多少.可以像dp一样从后往前推. 但有X的限制.所以该数组可以变成倍增 ...
- noip2012开车旅行 题解
题目大意: 给出n个排成一行的城市,每个城市有一个不同的海拔.定义两个城市间的距离等于他们的高度差的绝对值,且绝对值相等的时候海拔低的距离近.有两个人轮流开车,从左往右走.A每次都选最近的,B每次都选 ...
- noip2012 开车旅行
此题100分的解法就是先预处理出每个点的下一个点之后倍增就好了.其实并没有太大难度. pbihao用双向链表写过了此题.在本地上我treap狂操他,but在rqnoj上,我依靠反复提交才A掉此题(最后 ...
- Luogu 1081 [NOIP2012] 开车旅行
感谢$LOJ$的数据让我调掉此题. 这道题的难点真的是预处理啊…… 首先我们预处理出小$A$和小$B$在每一个城市的时候会走向哪一个城市$ga_i$和$gb_i$,我们有链表和平衡树可以解决这个问题( ...
随机推荐
- 20155222卢梓杰 实验一 逆向及Bof基础
实验一 逆向及Bof基础 1.实验对象为32位可执行文件pwn1,这个程序主要有main.foo.getshell这三个函数,其中foo函数功能为输出输入的字符串,getshell函数功能为打开一个s ...
- 20155336 虎光元《网络攻防》Exp2后门原理与实践
20155336 虎光元<网络攻防>Exp2后门原理与实践 一.实验内容 (1)使用netcat获取主机操作Shell,cron启动 (0.5分) (2)使用socat获取主机操作Shel ...
- Centos 发送smtp邮件
说明: 1.本文是用网易smtp服务,QQ的没试过 2.在Centos7上测试 实现: 1.关闭本机的sendmail服务或者postfix服务 ...
- STEAM 自动安装时提示C++ 安装不了等问题
[情况] 今天安装游戏, 安装时自动安装 Visual C++ 2015 x64 Minimum Runtime ....不成功, 提示网络源不可使用, 或者使用以下安装源 C:\ProgramDat ...
- exchange 2010 的两个错误
最近公司要搭建邮件服务器 过程中 碰到两个问题,记录下来. 引以为戒 . 1,登陆界面能出来 但是无论输入什么都显示 乱码.问题原因 身份验证有问题. 如图所示: 改成这个,然后 重启 iis 就可 ...
- JavaScript快速入门-ECMAScript函数
JavaScript函数(定义.参数.返回值.闭包.匿名函数) 一.函数定义 function functionName(arg0, arg1, ... argN) { statements } 函数 ...
- effective c++ 笔记 (5-8)
//---------------------------15/03/26---------------------------- //#5 了解c++默默编写并调用哪些函数 { /* c++会 ...
- 【容器魔方解读】AWS Re:Invent 2018大会
每年云计算领域技术与商业风向标之一的AWS Re:Invent大会上周在美国拉斯维加斯召开,如往届一样,AWS密集发布了上百项的新产品或新技术.随着国内近两年云计算尤其是公有云的普及度越来越高,国内各 ...
- 01-docker简介
如今Docker的使用已经非常普遍,特别在一线互联网公司.使用Docker技术可以帮助企业快速水平扩展服务,从而到达弹性部署业务的能力.在云服务概念兴起之后,Docker的使用场景和范围进一步发展,如 ...
- EOS开发基础之五:使用cleos命令行客户端操作EOS——智能合约之Exchange
先回答一下上一节中留下的问题,为什么我就看不到eosio这个账户中的钱呢?我明明为它create了很多token啊. 对,你是create了,但是没有issue啊.create了1000000000 ...