专栏文章
CF2005D Alter the GCD 题解
CF2005D题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @miqcls48
- 此快照首次捕获于
- 2025/12/04 02:36 3 个月前
- 此快照最后确认于
- 2025/12/04 02:36 3 个月前
有如下经典结论:设 为 的前/后缀 ,则 的取值只有 种。
考虑 从右向左做扫描线。
设:
动态维护 和本质不同的数对 。
显然只有 对。
且是一个不断单点删除,前缀加数的过程。
使用链表维护,时间复杂度 。
代码如下:
CPP#include<bits/stdc++.h>
using namespace std;
const int N=200005;
int a[N],b[N],R[N],qa[N],qb[N],ga[N],fa[N],gb[N],fb[N],n,ans;
long long cnt;
void solve()
{
ans=cnt=0;
cin>>n;
for(int i=1;i<=n;++i)
cin>>a[i],qa[i]=__gcd(qa[i-1],a[i]),ga[i]=gb[i]=0,R[i]=i+1;
for(int i=1;i<=n;++i)
cin>>b[i],qb[i]=__gcd(qb[i-1],b[i]);
int it,pre,u;
a[n+1]=b[n+1]=fa[n+1]=fb[n+1]=0;
for(int i=n;i>=1;--i)
{
it=i;
fa[i]=__gcd(fa[i+1],a[i+1]),fb[i]=__gcd(fb[i+1],b[i+1]);
while(it<=n)
ga[it]=__gcd(ga[it],a[i]),gb[it]=__gcd(gb[it],b[i]),it=R[it];
it=i+1,pre=i;
while(it<n)
{
if(ga[it]==ga[R[it]]&&gb[it]==gb[R[it]]&&fa[it]==fa[R[it]]&&fb[it]==fb[R[it]])
R[pre]=R[it],it=pre;
pre=it,it=R[it];
}
pre=i-1,it=i;
while(it<=n)
{
u=__gcd(qa[i-1],__gcd(gb[it],fa[it]))+__gcd(qb[i-1],__gcd(ga[it],fb[it]));
if(u>ans)
ans=u,cnt=it-pre;
else if(u==ans)
cnt+=it-pre;
pre=it,it=R[it];
}
}
cout<<ans<<' '<<cnt<<'\n';
}
int main()
{
ios::sync_with_stdio(0),cin.tie(0);
int T;
cin>>T;
while(T--)
solve();
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...