刚学OI的萌新求助
查看原帖
刚学OI的萌新求助
95072
wudiss8楼主2020/8/18 19:59

写的是斜率优化的正解,但不知道为什么最后一个点TLE了,求大佬帮忙卡常

#include<bits/stdc++.h>
using namespace std;
double sum[110001],po[110001];
int q[110001],n,k,pre[110001][211];
long long f[110001][211];
inline double xl(int j1,int j2){
	double g=sum[j2]-sum[j1];
	if(g==0)return -1e18;
    else
    return ((f[j1][k-1]*1.0-po[j1]*1.0)-(f[j2][k-1]*1.0-po[j2]*1.0))/g;
    //return (y(j1)-y(j2))/g;
}
inline bool xl1(int j1,int j2,int c){
	double g=sum[j2]-sum[j1];
    if(((f[j1][k-1]-po[j1])-(f[j2][k-1]-po[j2]))<=g*c)return 1;
    else
    return 0;
    //return (y(j1)-y(j2))/g;
}
inline int read(){
	char c=getchar();
	int qwq=0,awa=1;
	while(c<'0' or c>'9'){
		if(c=='-')awa=-1;
		c=getchar();
	}
	while(c>='0' and c<='9'){
		qwq=(qwq<<1)+(qwq<<3)+c-'0';
		c=getchar();
	}
	return qwq*awa;
}
signed main(){
	int K,a;
	n=read();K=read();
	for(register int i=1;i<=n;i++){
	    a=read();
	    sum[i]=sum[i-1]+a;
	    po[i]=sum[i]*sum[i];
    }
	for(k=1;k<=K;k++){
		int head=1,tail=1;
		q[tail]=0;
	    for(register int i=1;i<=n;i++){
	    	while(head<tail and xl1(q[head],q[head+1],sum[i]))head++;
	    	f[i][k]=f[q[head]][k-1]+(sum[i]-sum[q[head]])*sum[q[head]];
	    	pre[i][k]=q[head];
	    	while(head<tail and xl(q[tail-1],q[tail])>=xl(q[tail],i))tail--;
	    	tail++;q[tail]=i;
		}
    }
    printf("%lld\n",f[n][K]);
    int x=n;
    for(register int i=K;i>=1;i--){
    	x=pre[x][i];
    	printf("%d ",x);
	}
	return 0;
}
2020/8/18 19:59
加载中...