专栏文章
题解:P14221 [ICPC 2024 Kunming I] 学而时习之
P14221题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @mingcj6f
- 此快照首次捕获于
- 2025/12/02 01:57 3 个月前
- 此快照最后确认于
- 2025/12/02 01:57 3 个月前
思路:
根据题意,需要尝试所有可能的区间 ,将该区间内的元素都加 后,计算整个序列的最大公因数。
但是但是,如果直接模拟处理,时间肯定就炸飞了。
为了高效计算,可以预处理两个辅助数组:
:表示前 个元素的最大公因数。
:表示从 到 所有元素的最大公因数。
然后遍历每个可能的区间起点 ,若前缀最大公因数无变化则跳过。
从 开始扩展区间终点 ,计算区间 中的数加 后的最大公因数(记为 )。
结合 与区间右侧的后缀最大公因数,得到整个序列的最大公因数,并更新答案。
完结撒花~
Code
CPP#include<bits/stdc++.h>
using namespace std ;
const int maxn=3e5+5;
int n;
long long k,a[maxn],last_gcd[maxn],pre_gcd[maxn],s;
long long ans=0;
long long gcd (long long a, long long last_gcd) {
if (last_gcd==0) return a;
if (a%last_gcd==0) return last_gcd;
return gcd(last_gcd,a%last_gcd);
}
int main () {
int t;
cin>>t;
while (t--) {
cin>>n>>k;
for (int i=1;i<=n;i++) cin>>a[i];
for (int i=1;i<=n;i++) pre_gcd[i]=gcd(pre_gcd[i-1],a[i]);
last_gcd[n+1]=0;
for(int i=n;i>=1;i--) last_gcd[i]=gcd(last_gcd[i+1],a[i]);
ans=pre_gcd[n];
for (int i=1;i<=n;i++) {
if (pre_gcd[i]==pre_gcd[i-1]) continue;
s=pre_gcd[i-1];
for (int j=i;j<=n;j++) {
s=gcd(s,a[j]+k);
ans =max(ans,gcd(s,last_gcd[j+1]));
}
}
cout<<ans<<"\n";
}
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...