专栏文章
题解:CF2110F Faculty
CF2110F题解参与者 4已保存评论 3
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 3 条
- 当前快照
- 1 份
- 快照标识符
- @mip7h0t3
- 此快照首次捕获于
- 2025/12/03 07:24 3 个月前
- 此快照最后确认于
- 2025/12/03 07:24 3 个月前
这道题算是本场除 AB 外,代码最为简单的了,但是思维难度大。
我们先证明命题 :
证明:
若 则 。
否则设 。
此时 。
。
由于 ,命题得证。
再证明命题 :长度为 的前缀中最大的 ,,在 中取得。
证明:
设 为长度为 的前缀中的最大元素, 大于找到的值,,由前命题,得 。
我们再考虑 ,由于 ,得 。
最后证明命题三:若 ,则
证明:
,由 ,知 ,从而 。
借助上述三个命题得正确性,我们可以枚举了。设在长度为 的前缀中,最大值为 ,最大的 为 。
我们用以下步骤更新 :
- 若 ,利用命题 ,更新 ;
- 若 ,利用命题 ,更新 ;
- 若 ,直接暴力遍历数组。
由于每次在前缀最大值达到前一个最大值的两倍才会枚举数组内的所有元素,所以时间复杂度可以证明是 ,其中 。
代码:
CPP#include<bits/stdc++.h>
using namespace std;
int f(int x, int y) { return x % y + y % x; }
void solve(){
int n; cin >> n;
vector<int>a(n + 1);
for(int i = 1; i <= n; i++) cin >> a[i];
int ans = 0, maxn = a[1];
for(int i = 1; i <= n; i++){
ans = max(ans, f(maxn, a[i]));
if(a[i] > maxn){
if(a[i] >= maxn * 2){
maxn = a[i];
for(int j = 1; j <= i; j++) ans = max(ans, f(a[i], a[j]));
} else { maxn = a[i]; ans = maxn; }
}
cout << ans << ' ';
}
cout << '\n';
}
int main(){
int t = 1;
cin >> t;
while(t--){
solve();
}
return 0;
}
相关推荐
评论
共 3 条评论,欢迎与作者交流。
正在加载评论...