• 【CF#338D】GCD Table


    【题目描述】

    有一张N,M<=10^12的表格,i行j列的元素是gcd(i,j)

    读入一个长度不超过10^4,元素不超过10^12的序列a[1..k],问是否在某一行中出现过

    【题解】

    要保证gcd(x,y)=a[i],显然x=lcm(a[1],a[2]……a[k])

    然后y%a[1]=0,即(y+i-1)%a[i]=0

    即y%a[1]=0

    y%a[2]=-1

    ……

    y%a[n]=-(n-1)

    这就转化为了中国剩余定理

    求出y之后,只需验证gcd(x,y+i-1)=a[i]即可

     1 /*************
     2   CF#338D
     3   by chty
     4   2016.11.3
     5 *************/
     6 #include<iostream>
     7 #include<cstdio>
     8 #include<cstdlib>
     9 #include<cstring>
    10 #include<ctime>
    11 #include<cmath>
    12 #include<algorithm>
    13 using namespace std;
    14 typedef long long ll;
    15 ll n,m1,K,A,M,ans,lcm(1),m[10010],a[10010];
    16 inline ll read()
    17 {
    18     ll x=0,f=1;  char ch=getchar();
    19     while(!isdigit(ch))  {if(ch=='-')  f=-1;  ch=getchar();}
    20     while(isdigit(ch))  {x=x*10+ch-'0';  ch=getchar();}
    21     return x*f;
    22 }
    23 ll gcd(ll a,ll b) {return !b?a:gcd(b,a%b);}
    24 void exgcd(ll a,ll b,ll &g,ll &x,ll &y)
    25 {
    26     if(b==0)  {x=1; y=0; g=a; return;}
    27     exgcd(b,a%b,g,x,y);
    28     ll t=x;x=y;y=t-a/b*y;
    29 }
    30 ll China()
    31 {
    32     for(ll i=1;i<=K;i++)  a[i]=1-i;
    33     A=a[1],M=m[1];
    34     for(ll i=2;i<=K;i++)
    35     {
    36         ll k,y,da=a[i]-A,g;
    37         exgcd(M,m[i],g,k,y);
    38         if(da%g)  return -1;
    39         ll t=m[i]/g;
    40         k*=da/g;
    41         k=(k%t+t)%t;
    42         A+=k*M;
    43         M=M*m[i]/g;
    44         A=(A+M)%M;
    45     }
    46     return A;
    47 }
    48 bool check()
    49 {
    50     if(lcm>n)  return 0;
    51     ll ans=China();
    52     if(ans<0)  return 0;
    53     if(ans==0)  ans=lcm;
    54     if(ans+K-1>m1)  return 0;
    55     for(ll i=1;i<=K;i++)  if(gcd(lcm,ans+i-1)!=m[i])  return 0;
    56     return 1;
    57 }
    58 int main()
    59 {
    60     //freopen("cin.in","r",stdin);
    61     //freopen("cout.out","w",stdout);
    62     n=read();  m1=read();  K=read();
    63     for(ll i=1;i<=K;i++)  m[i]=read();
    64     for(ll i=1;i<=K;i++)
    65     {
    66         lcm=lcm/gcd(lcm,m[i])*m[i];
    67         if(lcm>n) break;
    68     }
    69     check()?puts("YES"):puts("NO");
    70     return 0;
    71 }
  • 相关阅读:
    理性即自由
    解决问题的思路是怎样的?
    联系的结构-深度思考
    思考力,才是真正的第一生产力-快思考、慢思考
    CentOS7在防火墙与端口上的操作
    linux如何查看nginx是否启动
    Git篇
    Git 常用命令总结
    siblings() 获得匹配集合中每个元素的同胞
    Mysql查看版本号的五种方式介绍
  • 原文地址:https://www.cnblogs.com/chty/p/6025535.html
Copyright © 2020-2023  润新知