专栏文章
[题解]P10260 [COCI 2023/2024 #5] Rolete
P10260题解参与者 2已保存评论 1
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 1 条
- 当前快照
- 1 份
- 快照标识符
- @mip1hr78
- 此快照首次捕获于
- 2025/12/03 04:37 3 个月前
- 此快照最后确认于
- 2025/12/03 04:37 3 个月前
信息学不是数学,所以乐子题解当乐子看看就行了 /lh
思路
大胆猜测,当查询的 变小时,用按钮的次数一定不会减少,于是上决策单调性可以直接秒掉。
接下来尝试证明一下。设允许的最高高度为 ,令 表示按 次按钮的代价, 表示按 次后还需要单独操作的贡献以达到 ,则当询问 时先按 次按钮的代价就是 。
把 表示出来,其中 表示 中 的元素数量, 表示 中 的元素之和, 表示 中 的元素之和, 表示 中 的元素数量:
考虑 与 的增量 :
显然 随 的增大而减小,且 是一个单谷函数。我们希望对于每一个询问每一次选择的 都尽量的小,因此我们的决策点 一定为最小的满足 的数。
由于 单调递减,因此对于一个较大的 其决策点 一定较小。于是满足决策单调性的定义,证毕!
Code
CPP#include <bits/stdc++.h>
#define re register
#define int long long
using namespace std;
const int N = 2e5 + 10;
const int inf = (int)(1e18) + 10;
int n,t,s,k,q,m;
int arr[N],cnt[N],sum[N],cst[N],ans[N];
inline int read(){
int r = 0,w = 1;
char c = getchar();
while (c < '0' || c > '9'){
if (c == '-') w = -1;
c = getchar();
}
while (c >= '0' && c <= '9'){
r = (r << 3) + (r << 1) + (c ^ 48);
c = getchar();
}
return r * w;
}
inline void dfs(int l,int r,int vl,int vr){
if (l > r) return;
int mid = l + r >> 1;
int Min = inf,pos = 0;
for (re int i = vl;i <= vr;i++){
int val = cst[i] + (sum[mid + i + 1] - (cnt[m] - cnt[mid + i]) * (i + mid)) * t;
if (Min > val) Min = val,pos = i;
} ans[mid] = Min;
dfs(l,mid - 1,pos,vr); dfs(mid + 1,r,vl,pos);
}
signed main(){
n = read(),t = read(),s = read(),k = read();
for (re int i = 1;i <= n;i++){
cnt[arr[i] = read()]++; sum[arr[i]] += arr[i];
} m = *max_element(arr + 1,arr + n + 1);
for (re int i = 1;i <= 2 * m;i++) cnt[i] += cnt[i - 1];
for (re int i = m;~i;i--) sum[i] += sum[i + 1];
for (re int i = 1;i <= m;i++) cst[i] = cst[i - 1] + s + k * cnt[i - 1];
dfs(0,m,0,m); q = read();
while (q--) printf("%lld ",ans[read()]);
return 0;
}
相关推荐
评论
共 1 条评论,欢迎与作者交流。
正在加载评论...