cfenglv的一道简单签到题 QDU

来源:互联网 发布:淘宝分享购物清单在哪 编辑:程序博客网 时间:2024/05/21 10:53

点击打开链接

越多个数求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;}

原创粉丝点击