越多个数求gcd 所得值越小 即区间越长所得值越小

二分区间长度 看在当前区间长度下能否通过rmq找到符合条件的区间即可

 

#include <bits/stdc++.h>
using namespace std;

int gcd(int a,int b)
{
int t;
while(b!=0)
{
t=b;
b=a%b;
a=t;
}
return a;
}

int dp[100010][20];
int num[100010];
int n,k,len,flag,ans;

void init();
void binsearch();
void calculate();

int main()
{
int t,i;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&k);
for(i=1;i<=n;i++)
{
scanf("%d",&num[i]);
}
init();
binsearch();
printf("%d\n",ans);
}
return 0;
}

void init()
{
int i,j;
for(i=1;i<=n;i++)
{
dp[i][0]=num[i];
}
for(j=1;j<=17;j++)
{
for(i=1;i+(1<<j)-1<=n;i++)
{
dp[i][j]=gcd(dp[i][j-1],dp[i+(1<<j-1)][j-1]);
}
}
return;
}

void binsearch()
{
int l,r,m;
l=1,r=n,ans=0;
while(l<=r)
{
m=(l+r)/2,len=m,flag=0;
calculate();
if(flag==0)
{
r=m-1;
}
else
{
l=m+1;
ans=len;
}
}
return;
}

void calculate()
{
int i,l,r,t;
t=log((double)(len))/log(2.0);
for(i=1;i+len-1<=n;i++)
{
l=i,r=i+len-1;
if(gcd(dp[l][t],dp[r-(int)(pow(2,t))+1][t])>=k)
{
flag=1;
return;
}
}
return;
}