传送门

解题思路

这道题刚了一下午,主要就刚在set那里了。先写了一个暴力70分。。之后优化预处理,看着大佬神犇们都用的什么双向链表之类的东西,本蒟蒻不会,又懒得手写平衡树,就拿了个set搞了搞,感觉做麻烦了,我开了两个set,一个存正数一个存负数。因为STL只能求后继,然后每次先求最小,删掉再求次小,再加回来。预处理复杂度应该是nlogn,交了一发75,看了看lyd的书才知道要倍增。f[i][j][0/1]表示一共走了2^i天,在j这个城市,轮A/B开车的到达的城市,如果i=1 f[i][j][k]=f[i-1][f[i-1][j][k]][1-k],意思就是走了2天,一人开了一天,所以由另一个人最后开转移来。如果i>1 f[i][j][k]=f[i-1][f[i-1][j][k]][k], 意思是每个人开了偶数天,所以前后两半的最后都是同一个人开,再预处理一个data表示路程,处理方法和f相近,最后卡了卡常。。

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<set>
#include<cmath> using namespace std;
const int MAXN = 100005;
typedef long long LL; inline LL rd(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)) {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return x*f;
} struct Pos{
int id;
LL high;
}pos[MAXN],rev[MAXN]; int n,m,nxt[MAXN][3],x0,st,f[22][MAXN][2];
LL ans[3],dis[MAXN][3],data[22][MAXN][2][2];
double K=1e9;
set<Pos> S,T;
bool operator <(const Pos &A,const Pos &B){
return A.high<B.high;
} int main(){
// freopen("random.txt","r",stdin);
// freopen("A.txt","w",stdout);
n=rd();int lg=log2(n);
for(register int i=1;i<=n;i++) pos[i].high=rd(),pos[i].id=i;
for(register int i=n;i;i--){
rev[i].high=-pos[i].high;rev[i].id=i;
LL mn1=1e18,mn2=1e18;int p1=-1,p2=-1;Pos A;int flag=0;
set<Pos>::iterator it=S.lower_bound(pos[i]);
if(it!=S.end()) {mn1=abs((*it).high-pos[i].high);p1=(*it).id;A=*it;flag=1;}
it=T.upper_bound(rev[i]);
if(it!=T.end() && abs(-((*it).high)-pos[i].high)<=mn1){
mn1=abs(-((*it).high)-pos[i].high);
p1=(*it).id;A=*it;flag=2;
}
Pos B;B.id=A.id;B.high=-A.high;
if(flag==1) S.erase(A),T.erase(B);
else if(flag==2) S.erase(B),T.erase(A);
if(flag){
it=S.lower_bound(pos[i]);
if(it!=S.end()) {mn2=abs((*it).high-pos[i].high);p2=(*it).id;}
it=T.upper_bound(rev[i]);
if(it!=T.end() && abs(-((*it).high)-pos[i].high)<=mn2){
mn2=abs(-((*it).high)-pos[i].high);
p2=(*it).id;
}
}
if(flag==1) S.insert(A),T.insert(B);
else if(flag==2) S.insert(B),T.insert(A);
S.insert(pos[i]);T.insert(rev[i]);
nxt[i][1]=p2,nxt[i][2]=p1;
dis[i][1]=mn2,dis[i][2]=mn1;
// cout<<i<<" "<<nxt[i][2]<<" "<<dis[i][2]<<endl;
f[0][i][0]=nxt[i][1];
f[0][i][1]=nxt[i][2];
data[0][i][0][0]=dis[i][1];
data[0][i][1][0]=0;
data[0][i][0][1]=0;
data[0][i][1][1]=dis[i][2];
}
for(register int i=1;i<=lg;i++)
for(register int j=1;j<=n;j++)
for(register int k=0;k<=1;k++){
if(i==1){
f[1][j][k]=f[0][f[0][j][k]][1-k];
data[1][j][k][0]=data[0][j][k][0]+data[0][f[0][j][k]][1-k][0];
data[1][j][k][1]=data[0][j][k][1]+data[0][f[0][j][k]][1-k][1];
continue;
}
f[i][j][k]=f[i-1][f[i-1][j][k]][k];
data[i][j][k][0]=data[i-1][j][k][0]+data[i-1][f[i-1][j][k]][k][0];
data[i][j][k][1]=data[i-1][j][k][1]+data[i-1][f[i-1][j][k]][k][1];
}
x0=rd();
for(register int i=1;i<=n;i++){
ans[1]=ans[2]=0;int p=i;
for(register int j=lg;j>=0;j--)
if(ans[1]+ans[2]+data[j][p][0][0]+data[j][p][0][1]<=x0){
ans[1]+=data[j][p][0][0];ans[2]+=data[j][p][0][1];
p=f[j][p][0];
}
if(ans[2]==0) {if(K==1e9 && pos[i].high>pos[st].high) st=i;continue;}
if((double)ans[1]/ans[2]<K || ((double)ans[1]/ans[2]==K && pos[i].high>pos[st].high)){
st=i;
K=(double)ans[1]/ans[2];
}
}
printf("%d\n",st);
m=rd();
for(register int i=1;i<=m;i++){
LL x=rd(),y=rd();
ans[1]=ans[2]=0;int p=x;
for(register int j=lg;j>=0;j--)
if(ans[1]+ans[2]+data[j][p][0][0]+data[j][p][0][1]<=y){
ans[1]+=data[j][p][0][0];ans[2]+=data[j][p][0][1];
p=f[j][p][0];
}
printf("%lld %lld\n",ans[1],ans[2]);
}
return 0;
}

LUOGU P1081 开车旅行 (noip 2012)的更多相关文章

  1. 开车旅行 [NOIP 2012]

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

  2. luogu P1081 开车旅行

    传送门 这题的暴力做法显然是照题意模拟,从每个点出发暴力跳.而这个暴跳显然是可以倍增优化的,就是预处理出从每个点,(一开始是A)往后跳\(2^k\)步,能到哪里,以及\(A\)和\(B\)的路程,然后 ...

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

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

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

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

  5. P1081 开车旅行

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

  6. NOIP 2012 洛谷P1081 开车旅行

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

  7. NOIP 2012 P1081 开车旅行

    倍增 这道题最难的应该是预处理... 首先用$set$从后往前预处理出每一个点海拔差绝对值得最大值和次大值 因为当前城市的下标只能变大,对于点$i$,在$set$中二分找出与其值最接近的下标 然后再$ ...

  8. P1081 开车旅行(Not Finish)

    https://www.luogu.org/problemnew/show/P1081

  9. noip2012 P1081 开车旅行

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

随机推荐

  1. SPSS与Streams的集成实现实时预测

    SPSS与Streams的集成实现实时预测 SPSS Modeler 是一个数据挖掘工作台,提供了一个可了解数据并生成预测模型的最先进的环境.Streams 提供了一个可伸缩的高性能环境,对不断变化的 ...

  2. 第一周——clone项目到本地

    公司使用的是git进行version control,代码托管在gitlab. 按照公司规范注册了gitlab账号, 漫长的等待clone到本地~ 然而,还是有问题,jar包下载不完全(公司网速dow ...

  3. charles-过滤网络请求方法

    方法一:在主界面的中部的 Filter 栏中填入需要过滤出来的关键字.例如我们的服务器的地址是:https://www.baidu.com , 那么只需要在 Filter 栏中填入 https://w ...

  4. COCI2014/2015 Contest#1 D MAFIJA【基环树最大独立点集】

    T1725 天黑请闭眼 Online Judge:COCI2014/2015 Contest#1 D MAFIJA(原题) Label:基环树,断环+树形Dp,贪心+拓扑 题目描述 最近天黑请闭眼在 ...

  5. Windows API 第三篇

    1.获得程序自身的路径: DWORD GetModuleFileName( HMODULE hModule, // handle to module LPTSTR lpFilename, // pat ...

  6. NOIP2018提高组初赛选讲

    说实话,这次的初赛比上一次的要简单. 不过还有些变态的题目. 在一条长度为1 的线段上随机取两个点,则以这两个点为端点的线段的期望 长度是( ). A. 1 / 2 B. 1 / 3 C. 2 / 3 ...

  7. Django项目:CRM(客户关系管理系统)--60--50PerfectCRM实现CRM客户报名流程学生合同URL随机码

    # sales_urls.py # ————————47PerfectCRM实现CRM客户报名流程———————— from django.conf.urls import url from bpm. ...

  8. vue.js_02_vue.js的基础指令

    1.v-cloak 作用:解决插值表达式闪烁的问题 当网速过慢时,或者加载数据时间过长时,网页会出现  {{msg}}  的现象 使用方法: <!--缺陷需要写style样式--> < ...

  9. VS2005编译VTK5.10.1

    1.从官方下载源文件和数据文件解压到同一个文件夹 2.下载并安装cmake 3.打开cmake选择VTK源文件路径和编译生成路径 注意:在路径里面不能出现中文字符!(我觉得以后的路径尽可能不要有中文字 ...

  10. C# 制作ActiveX控件并添加到网页

    1.创建ActiveX控件——按钮 2.定义一个接口,并在控件中实现 3.部署安装 4.CAB打包 5.添加到网页中进行测试 一. 创建ActiveX控件——按钮 1.新建一个Window窗体控件库项 ...