P1081 开车旅行 倍增 洛谷

题目连接

题意

题目已经说的hin明确了。

题解

我们要求出从每个点出发,小A要走的城市和小B要走的城市。

我们把ii以后的所有点的海拔加入到set,然后拿H[i]H[i]到set里面去lower_bound,找到比H[i]大的两个地点和比H[i]小的两个地点,并把这四个地点与H[i]的差值加入到新的排序数组中,排个序,找到差值最小的两个点,分别就是小B要选的目的地和小A要选的目的地。
在这里注意一点,就是当差值最小的两个值相等的时候,小B走的是海拔较低的那个点,涉及到第二关键字的问题,我们可以用一个比较省事的方法,那就是给海拔低的点计算差值时候乘以99999999,海拔较高的点计算差值时候乘以100000000。

定义需要的状态

nxt1[i]nxt1[i]代表从ii出发,小B的目的地。
nxt2[i]代表从ii出发,小A的目的地。
nxt3[i][j]代表从ii出发,(小A走完、小B走完)2j轮,所达到的目的
地。

DP1[i][j]DP1[i][j]代表从i出发,(小A走完、小B走完)2j2j轮,小B所经过的距离。

DP2[i][j]DP2[i][j]代表从i出发,(小A走完、小B走完)2j2j轮,小A所经过的距离。

nxt3,DP1,DP2可以用类似于处理ST表的方法求出来。

函数解释

一轮代表小A走一次+小B走一次。
getdp(int &S,int len,ll &ans1,ll &ans2)
从S出发,走len轮,返回ans1为小B走过的路程,返回ans2为小A走过的路程,并且把S改变为len轮以后到达的点。
getmx(int S,ll X)
从S出发,总路程不能超过X,返回最大能走几轮。

回答询问

给出SiSiXiXi,用二分的方法求出从Si出发小A和小B最长能走的长度。


代码

// luogu-judger-enable-o2
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <set>
using namespace std;
typedef long long ll;
typedef pair<ll,int> pll;
set<pll>::iterator it;
const int maxn = 500007;
int nxt1[maxn],nxt2[maxn],nxt3[maxn][30];
int N,LOG,X0,M;
ll H[maxn],H2[maxn],H1[maxn],DP2[maxn][30],DP1[maxn][30];
pll tmpsort[7];
void getdp(int &S,int len,ll &ans1,ll &ans2){int cnt = 0;while(len){if(len & 1){ans1 += DP1[S][cnt];ans2 += DP2[S][cnt];S = nxt3[S][cnt];}len >>= 1;cnt++;if(!S) break;}return ;
}
int getmx(int S,ll X){int l = 0,mid,r = N+1;while(r - l > 1){mid = (l+r)/2;int nS = S;ll ans1 = 0,ans2 = 0;getdp(nS,mid,ans1,ans2);if(ans1+ans2 > X || !nS)r = mid;else l = mid;}return l;
}
int main(){set<pll> st;cin>>N;int tmp = 1;while(tmp <= N/3)LOG++,tmp <<= 1;for(int i = 1;i <= N;++i){scanf("%lld",&H[i]);st.insert(make_pair(H[i],i));}for(int i = 1;i < N;++i){int ct = 0;st.erase(make_pair(H[i],i));it = st.lower_bound(make_pair(H[i],i));if(it != st.end()){tmpsort[ct++] = make_pair(abs(H[i]-(*it).first)*100000000,(*it).second);    ++it;}if(it != st.end()){tmpsort[ct++] = make_pair(abs(H[i]-(*it).first)*100000000,(*it).second);    }  it = st.lower_bound(make_pair(H[i],i));if(it != st.begin()) {--it;tmpsort[ct++] = make_pair(abs(H[i]-(*it).first)*99999999,(*it).second);    if(it != st.begin()){--it;tmpsort[ct++] = make_pair(abs(H[i]-(*it).first)*99999999,(*it).second); }}sort(tmpsort,tmpsort+ct);if(ct > 0)nxt1[i] = tmpsort[0].second;if(ct > 1)nxt2[i] = tmpsort[1].second;}for(int i = 1;i < N;++i)nxt3[i][0] = nxt1[nxt2[i]];for(int i =1;i <= N;++i){if(nxt1[i])H1[i] = abs(H[nxt1[i]] - H[i]);if(nxt2[i]){H2[i] = abs(H[nxt2[i]] - H[i]);DP2[i][0] = abs(H[nxt2[i]] - H[i]);}if(nxt1[nxt2[i]])DP1[i][0] = abs(H[nxt1[nxt2[i]]] - H[nxt2[i]]);}for(int j = 1;j <= LOG;++j){for(int i = 1;i <= N;++i){nxt3[i][j] = nxt3[nxt3[i][j-1]][j-1];DP1[i][j] = DP1[i][j-1] + DP1[nxt3[i][j-1]][j-1];DP2[i][j] = DP2[i][j-1] + DP2[nxt3[i][j-1]][j-1];}}int mf1 = 0,mf2 = 1,mh = 0;int ans1 = 1;cin>>X0>>M;for(int i = 1;i <= N;++i){ll f1 = 0,f2 = 0;int nS = i;int mxl = getmx(i,X0);getdp(nS,mxl,f1,f2);if(nxt2[nS] && H2[nS]+f1+f2 <= X0)f2 += H2[nS];if(!f2) continue;if(mf1*f2 < f1*mf2){mf1 = f1;mf2 = f2;ans1 = i;mh = H[i];}else if(mf1*f2 == mf2*f1 && H[i] > mh){mf1 = f1;mf2 = f2;ans1 = i;mh = H[i];}}cout<<ans1<<endl;for(int i = 0;i < M;++i){int Si,nSi;ll Xi;scanf("%d %lld",&Si,&Xi);nSi = Si;int mxl = getmx(Si,Xi);ll f1 = 0,f2 = 0;getdp(nSi,mxl,f1,f2);if(nxt2[nSi] && H2[nSi]+f1+f2 <= Xi)f2 += H2[nSi];printf("%lld %lld\n",f2,f1);}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/321268.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

nssl1454-最短路【并查集,贪心】

正题 题目大意 nnn个点&#xff0c;每个点可以走到[ai,n][a_i,n][ai​,n]&#xff0c;每个点可以从[bi,n][b_i,n][bi​,n]到达。 求disi,j∗(ij)dis_{i,j}*(ij)disi,j​∗(ij)的异或和 解题思路 首先我们可以知道肯定是先往后跳再往前走最优&#xff0c;因为如果先往前再往后…

.NET Core 跨平台执行命令、脚本

一.前言我们可能会遇到需要在程序中执行一些系统命令&#xff0c;来获取一些信息&#xff1b;或者调用shell脚本。.NET Core 目前已经可以跨平台执行&#xff0c;那么它如何跨平台执行命令呢&#xff0c;请看下面的讲解。二.ProcessStartInfo、Process 类介绍我们主要用到的两个…

nssl1458-HR 的疑惑【枚举】

正题 题目大意 给出nnn&#xff0c;求[1..n][1..n][1..n]中有多少个数可以被ab(b>1)a^b(b>1)ab(b>1)表示 解题思路 首先如果bbb等于222&#xff0c;那么可以被表示的数就是n\sqrt nn​个 bbb不是质数时&#xff0c;显然所以的数都可以被一个bbb是质数的情况表示。 …

性能是.NET Core的一个关键特性

关键要点.NET Core是跨平台的&#xff0c;可运行在Windows、Linux、Mac OS X和更多平台上&#xff1b;与.NET相比&#xff0c;发布周期要短得多。大多数.NET Core 都是通过NuGet软件包交付的&#xff0c;可以很容易地发布和升级。更快速的发布周期对性能提升工作以及改进诸如So…

简单的数学问题 洛谷 P1414 又是毕业季II

题意 给出n个数字&#xff0c;询问从中挑出k个数字&#xff0c;最大可能的公共gcd是多少。 题解 k个数的gcd一定出现至少k次。 我们遍历所有的数并对每个数字求它所有的因子&#xff0c;统计各个因子出现的个数。 给定k时&#xff0c;我们的答案就是所有出现次数>k的因…

【枚举】连续自然数和(jzoj 2102)

连续自然数和 题目大意&#xff1a; 输出一个n&#xff0c;求出所有相加等于n的连续自然数序列 样例输入 10000 样例输出 18 142 297 328 388 412 1998 2002 数据范围限制 10 < M < 2,000,000 解题思路&#xff1a; 这道题的正解的时间复杂度是o(2n)o\left …

nssl1460-逛机房【bfs】

正题 题目大意 nnn次询问&#xff0c;给出一个数xxx&#xff0c;每次可以进行操作 修改其中一个位&#xff0c;去掉前导零删掉其中一个位&#xff0c;去掉前导零 询问最少步骤使得xxx变为一个完全平方数 解题思路 我们可以从完全平方数开始广搜&#xff0c;操作变为 加入一…

将 ASP.NET Core 2.0 项目升级至 ASP.NET Core 2.1 RC 1

微软发布了 .NET Core 2.1 RC 1 &#xff0c;虽然只是 Release Candidate 版&#xff0c;但已经可以在生产环境中使用。NET Core 2.1 RC is supported by Microsoft and can be used in production..NET Core 2.1 的性能大提升早让人垂涎三尺&#xff0c;看到这个消息后&#x…

洛谷P1169 树上分组背包

题解 第一次写树上分组背包的题目。 什么是分组背包&#xff1f; 分组背包就是将物品进行分组每组内部只能选择一类物品。 for(int i 1;i < N;i){for(int j 0;j < V;j){for(int k 0;k < item[I];k){dp[i][j] max(dp[i][j],dp[i-1][j-v[i][k]]w[i][k]); }} …

【dfs】简单游戏(jzoj 2121)

简单游戏 题目大意 原本有n个数字&#xff0c;第1,2个相加&#xff0c;第2&#xff0c;3个相加……第n-1,n个相加&#xff0c;由此得出一个长度为n-1的新序列&#xff0c;然后不停重复&#xff0c;最后得出一个t&#xff0c;现在给出一开始的n和t求符合的序列&#xff08;字典…

nssl1459-空间简单度【扫描线,线段树】

正题 题目大意 nnn个点的一颗树&#xff0c;合法路径定义为一条路径上每个点的编号相差大于KKK。求合法路径数 解题思路 首先我们可以求不合法的路径数&#xff0c;这样我们就有了K∗nK*nK∗n个不合法&#xff08;即不能在同一个路径上&#xff09;的点对。 然后这题就和之前…

ASP.NET Core Identity Hands On(2)——注册、登录、Claim

上一篇文章&#xff08;ASP.NET Core Identity Hands On&#xff08;1&#xff09;——Identity 初次体验&#xff09;中&#xff0c;我们初识了Identity&#xff0c;并且详细分析了AspNetUsers用户存储表&#xff0c;这篇我们将一起学习Identity 默认生成的样板代码的注册与登…

洛谷 动态规划一日游 P2577、P1070、P2051

记 2018年3月19日 贼颓呢&#xff0c;一天就写了两道DP&#xff0c;还都不会写&#xff0c;这可GG。 动态规划真的难且有趣&#xff0c;算法题中动态规划占到了很大的比例&#xff0c;而且动态规划往往是辅助解决一些其他类型问题的基础&#xff0c;加深加强对动态规划问题的…

【DP】【高精】幸运票 (jzoj 2122)

幸运票 题目大意&#xff1a; 一个长度为2N的序列&#xff0c;这些数的总和为S&#xff0c;当这个序列的前N个和后N个总和相等时&#xff0c;它是符合题意的&#xff0c;问有符合题意的有多少种可能 样例输入 2 2 样例输出 4 数据范围限制 1<N<50 S<1000 解…

51nod-有限背包计数问题【dp】

正题 题目链接:http://www.51nod.com/Challenge/Problem.html#problemId1597 题目大意 nnn种物品&#xff0c;第iii个大小为iii且有iii个。 求恰好填满大小为nnn的背包的方案数 解题思路 我们可以将背包分为两份&#xff0c;对于大小小于等于n\sqrt nn​的物品&#xff0c;这…

Build 2018大会:.NET概述和路线图

在Microsoft Build 2018大会上&#xff0c;.NET项目管理主管Scott Hunter和.NET社区主管Scott Hanselman举行了一场有关.NET未来发展的会谈。会谈指出&#xff0c;未来.NET平台将可以搭建任何类型的应用程序&#xff1a;桌面程序、web程序、云程序、移动应用、游戏应用、物联网…

洛谷P2278操作系统 模拟+堆

一道模拟题 竟然活生生的不会模拟&#xff0c;感觉自己好菜啊。 在模拟的时候&#xff0c;一定要弄清楚要对什么进行模拟。 题解 进程的等待队列是一个优先队列&#xff0c;优先队列是以优先级降序作为第一关键字&#xff0c;以进入时间为第二关键字。在操作系统这道题目中…

【二分】抄书 (jzoj 2123)

抄书 题目大意&#xff1a; 有n本书&#xff0c;分给m个人抄&#xff0c;每个人只能拿到连续的书&#xff08;不能把一本书分开&#xff09;&#xff0c;问抄书最多的人要抄多少页 样例输入 9 3 100 200 300 400 500 600 700 800 900 样例输出 1700 数据范围限制 对于…

nssl1467-U【差分】

正题 题目大意 n∗nn*nn∗n的矩阵&#xff0c;每次让一个下三角形内数字加上一定权值。求最后所有位置的异或和 解题思路 我们发现如果我们对于没行做前缀和的话&#xff0c;我们需要修改的位置就是一个竖直下去的一列和斜着的一条&#xff0c;所以我们可以分别对于竖着的和斜…

汽车之家汽车品牌Logo信息抓取 DotnetSpider实战[三]

一、正题前的唠叨第一篇实战博客&#xff0c;阅读量1000&#xff0c;第二篇&#xff0c;阅读量200&#xff0c;两篇文章相差近5倍&#xff0c;这个差异真的令我很费劲&#xff0c;截止今天&#xff0c;我一直在思考为什么会有这么大的差距&#xff0c;是因为干货变少了&#xf…