专栏文章
题解:P11333 [NOISG2020 Finals] Discharging
P11333题解参与者 2已保存评论 2
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 2 条
- 当前快照
- 1 份
- 快照标识符
- @miqmcpll
- 此快照首次捕获于
- 2025/12/04 07:09 3 个月前
- 此快照最后确认于
- 2025/12/04 07:09 3 个月前
Solution
考虑如果某一段 的最大值为 ,则必定有 ,否则 肯定更优。
因此我们只考虑前缀最大值之间的转移,可以令 ,答案不变。
这样就有
显然可以斜率优化。
CPP#include<bits/stdc++.h>
#define int long long
#define _ ((__int128)1)
#define ffor(i,a,b) for(int i=(a);i<=(b);i++)
#define roff(i,a,b) for(int i=(a);i>=(b);i--)
using namespace std;
const int MAXN=1e6+10;
int n,a[MAXN],dp[MAXN],tot,pos=1;
struct Node {int x,y;}st[MAXN];
void insert(int x,int y) {
while(tot>1&&_*(y-st[tot].y)*(st[tot].x-st[tot-1].x)<_*(st[tot].y-st[tot-1].y)*(x-st[tot].x)) tot--;
return st[++tot]={x,y},void();
}
signed main() {
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
cin>>n;
ffor(i,1,n) cin>>a[i];
ffor(i,1,n) a[i]=max(a[i],a[i-1]);
insert(0,0);
ffor(i,1,n) {
while(pos<tot&&_*a[i]*(st[pos+1].x-st[pos].x)>st[pos+1].y-st[pos].y) pos++;
while(pos>1&&_*a[i]*(st[pos].x-st[pos-1].x)<st[pos].y-st[pos-1].y) pos--;
dp[i]=n*a[i]+st[pos].y-st[pos].x*a[i];
insert(i,dp[i]),pos=min(pos,tot);
}
cout<<dp[n];
return 0;
}
相关推荐
评论
共 2 条评论,欢迎与作者交流。
正在加载评论...