博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
环路运输
阅读量:6673 次
发布时间:2019-06-25

本文共 1146 字,大约阅读时间需要 3 分钟。

给出一个长度为n序列\(a_i\),定义第i个位置和第j个位置的距离为\(s[i][j]=\min(|i-j|,n-|i-j|)\),定义两个位置的权值为\(a_i+a_j+s[i][j]\),询问最大的权值,\(n\leq 10^6\)

注意到所谓的距离,即环上的距离公式,所以问题与环有关,于是拆环成链,再补一截一模一样的序列在原序列后,不妨按照区间问题的解决办法,枚举一个右端点i,再枚举左端点j,自然\(i>j\),设\(i-j\leq n/2\)

\(i-j\leq n/2:\)

此时,显然可以在新序列上表现旧序列i,j的距离

\(i-j> n/2\)

此时存在另外一个\(j'=j+n\),满足i,j'间距离\(j'-i=j+n-i=n-|i-j|\)

于是只要在环上满足\(i-j\leq n/2\),就可以表现原序列也即环的所有的距离,其实也可以这样感性理解,因为所谓的再补一截,也就是一条穿越原来的环2次的路径,对于其中一小段路径的长度记做s1,对于这一小段路径的两个端点,在环上互达有两条路径,较小的那条为距离,于是当\(s1\leq n/2\),必然为所谓的距离。

于是我们只要枚举右端点,在枚举合法的左端点,寻找它们的最大值,这个我们时是可以利用单调递减的单调队列维护的。

参考代码:

#include 
#include
#include
#define il inline#define ri register#define pi pair
using namespace std;deque
Q;int a[2000001];il int max(int,int);int main(){ int n,n2,ans(0);scanf("%d",&n),n2=n<<1; for(int i(1);i<=n;++i)scanf("%d",&a[i]),a[i+n]=a[i]; for(int i(1),j;i<=n2;++i){ while(Q.size()&&Q.front().first
>1))Q.pop_front(); if(Q.size())ans=max(ans,Q.front().second+a[i]+i); while(Q.size()&&Q.back().second
b?a:b;}

转载于:https://www.cnblogs.com/a1b3c7d9/p/10931751.html

你可能感兴趣的文章
PHP类推荐:QueryList|基于phpQuery的无比强大的PHP采集工具
查看>>
windows下实现wamp与tomcat环境整合
查看>>
我的友情链接
查看>>
Windows Server 2012 R2搭建IIS服务器
查看>>
SCVMM 2012 R2运维管理二之:安装域控制器
查看>>
[Fibre Channle 实战之三]FC 和iSCSI的使用差异
查看>>
c#winform选择文件,文件夹,打开指定目录方法
查看>>
traceroute
查看>>
如何划分man文档的章节
查看>>
微信公众号的分类
查看>>
分布式高可用存储(drbd+corosync+pacemaker+MooseFS)
查看>>
Nginx+Lua+Redis连接池
查看>>
MySQL python 数据迁移脚本
查看>>
我的友情链接
查看>>
网站运维常用小技巧,排错必备
查看>>
Python中MySQLdb模块的安装
查看>>
windows下的grep
查看>>
find 详解
查看>>
【书签】valgrind - the dynamic analysis tools
查看>>
zookeeper-体验原生api
查看>>