当前位置: 首页 > news >正文

题解:P8067 [BalkanOI 2012] balls

题意

给出一个长为 \(n\) 的序列,让你选择一段长度 \(\ge 2\) 区间内所有值变为区间右或左端点的值,最大化操作后的权值和。

思路

以第一问为例,选择一段区间 \((l,r]\) 后权值和的变化量为:

\[(r-l)\times a_r-(sum_r-sum_l) \]

其中 \(sum_i=\sum\limits_{j=1}^{i}a_j\)。把式子拆开,发现是如下的形式:

\[r\times a_r-sum_r-l\times a_r+sum_l \]

\(r\) 固定时,这是一个关于 \(l\) 的一次函数。不妨设 \(y=-a_r\times l+sum_l\),那么要最大化原式的值,就是要最大化这条直线的斜率。于是套路地在凸包上三分即可。

第二问把第一问的数组翻转再跑一遍即可。

代码

#include <bits/stdc++.h>
using namespace std;
#define ll long long
constexpr int N=3e5+5;
int n,a[N];
ll sum[N];
pair<int,ll>operator-(const pair<int,ll>&x,const pair<int,ll>&y){ // 计算x->y的向量return {x.first-y.first,x.second-y.second};
}
ll operator*(const pair<int,ll>&x,const pair<int,ll>&y){ // 计算向量叉积return x.first*y.second-x.second*y.first;
}
struct ConvexHull{ // 凸包vector<pair<int,ll>>st;void clear(){st.clear();}void insert(pair<int,ll>x){while(st.size()>=2&&(st[st.size()-2]-st.back())*(x-st.back())<=0)st.pop_back();st.push_back(x);}ll query(ll k){assert(st.size());if(st.size()==1)return k*st[0].first+st[0].second;int l=0,r=st.size()-1;while(r-l>1){ // 三分const int mid=(l+r)>>1;if(st[mid-1].first*k+st[mid-1].second<st[mid+1].first*k+st[mid+1].second)l=mid;else r=mid;}return max(k*st[l].first+st[l].second,k*st[r].first+st[r].second);}
}ch;
signed main(){ios::sync_with_stdio(false);cin.tie(0),cout.tie(0);cin>>n;for(int i=1;i<=n;i++)cin>>a[i];for(int i=1;i<=n;i++)sum[i]=sum[i-1]+a[i];ch.clear();ch.insert({0,0});ll ans=-1e18;for(int i=2;i<=n;i++){ // 注意区间左右端点不能相同,所以从2开始ans=max(ans,ch.query(-a[i])-sum[i]+1ll*i*a[i]);ch.insert({i-1,sum[i-1]});}cout<<sum[n]+ans<<'\n';reverse(a+1,a+n+1);for(int i=1;i<=n;i++)sum[i]=sum[i-1]+a[i];ch.clear();ch.insert({0,0});ans=-1e18;for(int i=2;i<=n;i++){ans=max(ans,ch.query(-a[i])-sum[i]+1ll*i*a[i]);ch.insert({i-1,sum[i-1]});}cout<<sum[n]+ans<<'\n';return 0;
}
http://www.hskmm.com/?act=detail&tid=15723

相关文章:

  • 题解:P8300 [COCI 2012/2013 #2] INSPEKTOR
  • SuperHarness-3D低压柜机电协同设计方案!
  • 详细介绍:.NET驾驭Word之力:打造专业文档 - 页面设置与打印控制完全指南
  • 使用.NET标准库实现多任务并行处理的详细过程 - 实践
  • 模型训练中 平均损失值和平均准确率的深入理解
  • torch.max函数在分类问题中的使用 学习
  • godot3.6字典遍历
  • 国产DevOps工具链崛起:Gitee领衔的本土化技术生态全景解读
  • 安装 elasticsearch-9.1.4的 IK分词器
  • react性能优化
  • 从研发效能到知识中枢:Gitee Wiki如何重塑企业知识管理范式
  • Gitee DevSecOps平台:军工软件研发的智能化革命
  • 杆状病毒表达系统为何成为蛋白表达首选
  • 日记3
  • Gitee如何重塑中国开发者的代码托管体验
  • 模块化面向对象 2章
  • css `isolation: isolate` - 详解
  • Debezium + Kafka + Flink/Doris Stream Load 实时数仓
  • Gitee DevOps平台:中国企业数字化转型的代码管理新范式
  • Ansible + Docker 部署 Zookeeper 集群
  • 幂运算与航班中转的奇妙旅行:探索算法世界的两极 - 实践
  • Gemini CLI 配置问题
  • 本土化与全球化博弈下的项目管理工具选型:Gitee如何为中国企业破局?
  • 论Linux安装后需要进行的配置
  • 51单片机-驱动DS1302时钟芯片模块教程 - 实践
  • tomato WP复盘
  • SQLite的并发问题
  • 域渗透靶场-vulntarget-a综合靶场
  • 数组和链表读取、插入、删除以及查找的区别
  • day 09 课程