我发的题解因“未按规定排版”被打回了,哪个大牛帮忙看看错在哪了,悬赏一个关注(通过后生效)
题解内容:
解决这题需要分以下步骤:
long long gcd(long long x,long long y) 函数来处理b数组;flag1[i-2] );flag2[i+1] );gcd(a[i-1],a[i+1]) 是否合法。注意边界特判。
不理解的,可以看图。(纠正:图片左下角的 flag[i-2] 应改为 flag1[i-2] 。)

#include<iostream>
#include<cstring>
using namespace std;
long long a[200005],b[200005],n;
long long gcd(long long x,long long y)
{
//欧几里得算法求最大公因数
return y==0?x:gcd(y,x%y);
}
bool check()
{
bool flag1[200005],flag2[200005];//flag1[i]表示从b[1]到b[i]是否不降,flag2[i]表示从b[i]到b[n-1]是否不降
b[n]=2e9;
for(int i=1;i<n;i++)
{
b[i]=gcd(a[i],a[i+1]);//预处理b[i]
}
flag1[0]=true;
for(int i=1;i<n;i++)
{
flag1[i]=flag1[i-1]&&b[i]>=b[i-1];//计算前缀
}
flag2[n-1]=flag2[n]=true;
for(int i=n-2;i>=1;i--)
{
flag2[i]=flag2[i+1]&&b[i]<=b[i+1];//计算后缀
}
int ans=flag1[n-2]|flag2[2];//特判
for(int i=2;i<n;i++)
{
int k=gcd(a[i-1],a[i+1]);
ans|=(
flag1[i-2]&&//前缀
flag2[i+1]&&//后缀
k>=b[i-2]&&
k<=b[i+1]//匹配左右
);
}
return ans;
}
int main()
{
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(false);
int t;
cin>>t;
while(t--)
{
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
if(check())
{
cout<<"YES\n";
}
else
{
cout<<"NO\n";
}
}
return 0;
}
一定要小心第 31~37 行的写法!