社区讨论

本人妹子,刚学OI,被毒瘤了88pts,求助

P3648[APIO2014] 序列分割参与者 5已保存回复 15

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
15 条
当前快照
1 份
快照标识符
@mi7xjkxl
此快照首次捕获于
2025/11/21 05:14
4 个月前
此快照最后确认于
2025/11/21 06:38
4 个月前
查看原帖
最后一个点比答案少了5,看8懂呃
CPP
#include<bits/stdc++.h>
using namespace std;
const int maxn=100010,maxk=210;
long long f[maxn],g[maxn],s[maxn];
int n,K1;
int pre[maxn][maxk],q[maxn];
double X(int i){
	return s[i];
}
double Y(int i){
	return g[i]-s[i]*s[i];
}
double K(int i,int j){
	double mo=X(j)-X(i);
	return !mo ? -1e18 : (Y(i)-Y(j))/mo;
}
int main(){
	cin>>n>>K1;
	for(int i=1;i<=n;i++){
		scanf("%lld",&s[i]);
		s[i]+=s[i-1];
	} 
	for(int k=1;k<=K1;k++){
		int head=1,tail=1;q[1]=0;
		for(int i=1;i<=n;i++){
			while(head<tail && K(q[head],q[head+1])<=s[i]) head++;
			int j=q[head];
			f[i]=g[j]+(s[i]-s[j])*s[j];
			pre[i][k]=j;
			while(head<tail && K(q[tail],q[tail-1])>=K(i,q[tail])) tail--;
			q[++tail]=i;
		}
		memcpy(g,f,sizeof(g));
	}
	printf("%lld\n",f[n]);
	for(int i=K1,u=n;i>=1;i--){
		u=pre[u][i];
		printf("%d ",u);
	}
	return 0;
}


//f[i]=g[j]+(s[i]-s[j])*s[j];
//
//-s[i]*s[j]+f[i]=g[j]-s[j]*s[j];

回复

15 条回复,欢迎继续交流。

正在加载回复...