71pts TLE 求调
查看原帖
71pts TLE 求调
685964
shuqiang楼主2025/7/30 19:47

这个代码还可以怎么优化?

#include<iostream>
#include<queue>

using namespace std;
typedef long long ll;
typedef long double ld;

const int N = 1e5 + 10, K = 210;
int n, k, a[N], g[N][K], l, r; ll f[N][K], s[N], ans = 0, ansn;
vector<int> ansls;

inline int read_int(){
    int x = 0; char c = getchar(); while (!isdigit(c)) c = getchar();
    while (isdigit(c)) x = x*10 + (c^48), c = getchar(); return x;
}

struct point{
	ll x, y; int id;
	
	bool operator < (const point & o) const{
		return x < o.x;
	}
} q[N];

ld get_k(ll ax, ll ay, ll bx, ll by){
	return (ld)(ay - by) / (ax - bx);
}

int main(){
	n = read_int(); k = read_int();
	for(int i = 1; i <= n; i++) a[i] = read_int();
	for(int i = 1; i <= n; i++) s[i] = s[i-1] + a[i];
	for(int j = 1; j <= k; j++){
		l = 1, r = 0;
		for(int i = 1; i < n; i++){
			while(r-l+1 >= 2){
				point tp = q[r--];
				if(get_k(tp.x, tp.y, q[r].x, q[r].y) > get_k(s[i-1], f[i-1][j-1]-s[n]*s[i-1], tp.x, tp.y)){
					q[++r] = tp;
					break;
				}
			}
			q[++r] = (point){s[i-1], f[i-1][j-1]-s[n]*s[i-1], i-1};
			while(r-l+1 >= 2){
				point tp = q[l++];
				if(get_k(q[l].x, q[l].y, tp.x, tp.y) < -s[i]){
					q[--l] = tp;
					break;
				}
			}
			f[i][j] = f[q[l].id][j-1] + (s[i] - s[q[l].id]) * (s[n] - s[i]);
			g[i][j] = q[l].id;
		}
	}
	for(int i = 1; i < n; i++){
		if(f[i][k] >= ans){
			ans = f[i][k];
			ansn = i;
		}
	}
	for(int i = k; i >= 1; i--){
		ansls.push_back(ansn);
		ansn = g[ansn][i];
	}
	cout << ans << '\n';
	for(int j = ansls.size()-1; j >= 0; j--) cout << ansls[j] << ' ';
	return 0;
}
2025/7/30 19:47
加载中...