2008年第33届ACM/ICPC亚洲区预赛(合肥)网络预选赛_1007 The Luckies number

来源:互联网 发布:大学从不逃课 知乎 编辑:程序博客网 时间:2024/04/30 03:31

BT数论题

求解10^x = 1 (mod 9*L/gcd(L,8))的满足x>0的最小解就是答案

由8构成的数A设有x位
那么A=8(10^0+10^1+...+10^(x-1));
很容易得到A=(8/9)*(10^x-1);
题目的要求就是A=0(mod L)
就是(8/9)*(10^x-1)=0(mod L);
->8*(10^x-1)=0(mod 9L);
->10^x-1=0(mod 9L/gcd(L,8));
->10^x =1 (mod 9L/gcd(L,8));


解法是先求phi(9L/gcd(L,8)),然后枚举其因子

比如:L=11;9L/gcd(L,8)=99;phi(9L/gcd(L,8))=10;解得10^2 =1 (mod 99),2是满足条件的最小的因子了

顺便给出1999999999的答案:
161290320

其间要求 素数选取 求欧拉函数 素因子分解 解模方程...涉及很多方面的综合题...

 

  1. #include <iostream>
  2. using namespace std;
  3. typedef unsigned long long llong;
  4. bool prime[45000]={true,true};
  5. llong l,fac[32][2],ans;
  6. double eul;
  7. int p[45000],top,len=0;
  8. llong pro(llong x,llong y,llong n)
  9. {
  10.     llong ret=0,tmp=x%n;
  11.     for(;y;y>>=1)
  12.         {
  13.             if(y&0x1)
  14.                 if((ret+=tmp)>n)ret-=n;
  15.             if((tmp<<=1)>n)tmp-=n;
  16.         }
  17.     return ret;
  18. }
  19. llong pow_mod(llong a,llong b,llong c)
  20. {
  21.     llong ret;
  22.     for(ret=1;b;b>>=1)
  23.     {if(b&1) ret=pro(ret,a,c);a=pro(a,a,c);}
  24.     return ret;
  25. }
  26. llong gcd(llong a,llong b){return b?gcd(b,a%b):a;}
  27. void dfs(int dep,llong val)
  28. {
  29.     int i;llong ret=1;
  30.     if(dep==top)
  31.         {
  32.             if(pow_mod(10,val,l)==1&&val<ans)ans=val;
  33.             return;
  34.         }
  35.     for(i=0;i<=fac[dep][0];i++)
  36.         {
  37.             dfs(dep+1,val*ret);    
  38.             ret*=fac[dep][1];
  39.         }
  40. }
  41. int main()
  42. {
  43.     llong n;
  44.     int i,j,id=0;
  45.     for(i=2;i<=213;i++)if(!prime[i])for(j=i;j*i<45000;j++)prime[i*j]=true;
  46.     for(i=2;i<45000;i++)if(!prime[i])p[len++]=i;
  47.     while(scanf("%lld",&n)!=EOF,n)
  48.         {
  49.             printf("Case %d: ",++id);
  50.             ans=10000000000;
  51.             top=0;
  52.             l=9*n/gcd(n,8);
  53.             eul=n=l;
  54.             for(i=0;i<len;i++)
  55.                 {
  56.                     if(n%p[i]==0)
  57.                         {
  58.                             fac[top][0]=0;
  59.                             fac[top][1]=p[i];
  60.                             while(n%p[i]==0)
  61.                                 {
  62.                                     fac[top][0]++;
  63.                                     n/=p[i];
  64.                                 }
  65.                             top++;
  66.                             if(n==1||(n<45000&&!prime[n]))break;
  67.                         }
  68.                 }
  69.             if(n!=1){fac[top][0]=1;fac[top][1]=n;top++;}
  70.             for(i=0;i<top;i++)eul*=(1.0-1.0/(double)fac[i][1]);
  71.             n=eul;
  72.             top=0;
  73.             for(i=0;i<len;i++)
  74.                 {
  75.                     if(n%p[i]==0)
  76.                         {
  77.                             fac[top][0]=0;
  78.                             fac[top][1]=p[i];
  79.                             while(n%p[i]==0)
  80.                                 {
  81.                                     fac[top][0]++;
  82.                                     n/=p[i];
  83.                                 }
  84.                             top++;
  85.                             if(n==1||(n<45000&&!prime[n]))break;
  86.                         }
  87.                 }
  88.             if(n!=1){fac[top][0]=1;fac[top][1]=n;top++;}
  89.             dfs(0,1);
  90.             printf("%lld/n",ans==10000000000?0:ans);
  91.         }
  92. }
原创粉丝点击