题意:一个正整数序列,求 l,r 使 \(\sum_{i = 1}^{l - 1} a[i] + \Pi_{i = l}^r a[i] + \sum_{i = r + 1}^n a[i]\) 最大,\(a[i] < 10^9\)。
诈骗题。
如果在 \([l, r]\) 间乘积的 \(T\) 中去除一个数 \(x\),对答案的贡献为 \(f(x) = x - T / x\)。
由于是单增的,若去除任意一个 x 都不会变优,则
\(f(10^9) < 0\),\(T > 10^{18}\)。
所以一旦整个序列之积 \(> 10^{18}\),\(l\) 即为最左侧 \(> 1\) 的位置,\(r\) 为最右侧 \(> 1\) 的位置。
否则,大于 \(1\) 的数的个数 \(< 60\),枚举左右端点即可。
实际上这个上界远小于 \(10^{18}\),只不过这样更好想且也能轻松通过。
void solve() {
int n; cin >> n;
vector<ll> a(n + 1), sum(n + 1, 0), mul(n + 1, 1);
vector<int> pos;
rep(i, 1, n) cin >> a[i];
rep(i, 1, n) {
if(mul[i - 1] > 1e15 / a[i]) {
int l = 1, r = n ;
while(l < n && a[l] == 1) ++ l;
while(r > 1 && a[r] == 1) -- r;
return cout << l << ' ' << r << '\n', void();
}
if(a[i] > 1) pos.pb(i);
sum[i] = sum[i - 1] + a[i];
mul[i] = mul[i - 1] * a[i];
}
int l = 1, r = 1;
ll ans = 0;
for(int i : pos) {
for(int j : pos) {
if(i <= j) {
if(sum[i - 1] + (mul[j] / mul[i - 1]) + (sum[n] - sum[j]) > ans) {
ans = sum[i - 1] + (mul[j] / mul[i - 1]) + (sum[n] - sum[j]);
l = i;
r = j;
}
}
}
}
cout << l << ' ' << r << '\n';
}
标签:CF1872G,10,int,sum,pos,ans,mul
From: https://www.cnblogs.com/Luxinze/p/18011909