蓝题训练9.24P3648 [APIO2014] 序列分割
P3648 [APIO2014] 序列分割
Tag: 略
题意:略
题解:斜率优化
参考代码
#include<bits/stdc++.h>
using namespace std;
using ll=long long;
const ll maxn=100010;
ll f[2][maxn],pre[210][maxn];
ll head,tail,n,k,a[maxn];
struct vec{
ll id,x,y;
ll operator()(ll v){
return x*v+y;
}
}q[maxn];
ll cross(vec a,vec b,vec c){
a.x-=b.x;a.y-=b.y;
b.x-=c.x;b.y-=c.y;
return b.x*a.y-b.y*a.x;
}
void solve(){
cin>>n>>k;
for(int i=1;i<=n;i++) {
cin>>a[i];
a[i]+=a[i-1];
}
for(int t=1;t<=k;t++){
head=tail=0;
q[0]={0,0,0};
for(int i=1;i<=n;i++){
while(head<tail&&q[head](a[i])<=q[head+1](a[i])){
++head;
}
f[t&1][i]=q[head](a[i]);
pre[t][i]=q[head].id;
vec x={i,a[i],f[t&1^1][i]-a[i]*a[i]};
while(head<tail&&cross(q[tail-1],q[tail],x)<=0){
--tail;
}
q[++tail]=x;
}
}
cout<<f[k&1][n]<<"\n";
ll now=n;
for(int i=k;i>=1;i--){
cout<<pre[i][now]<<' ';
now=pre[i][now];
}
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
ll T=1;
while(T--) solve();
}

浙公网安备 33010602011771号