zoukankan      html  css  js  c++  java
  • poj3696 快速幂的优化+欧拉函数+gcd的优化+互质

    这题满满的黑科技orz

    题意:给出L,要求求出最小的全部由8组成的数(eg: 8,88,888,8888,88888,.......),且这个数是L的倍数

    sol:全部由8组成的数可以这样表示:((10^x)-1)*(8/9)

    那么有m=((10^x)-1)*(8/9)=k*L,answer即满足条件的最小的x

    性质1:若ax=by且a和b互质,那么说明a中没有任何b的质因子,b的质因子一定在x里。所以x是b的倍数。

    所以先想方设法在等式中构造两个互质的数以便化简。我们取p=8/gcd(8,L),q=9*L/gcd(8,L)

    那么有p*((10^x)-1)=q*k,且p与q互质【8/gcd(8,L)与L/gcd(8,L)一定互质。8又没有3这个质因子,所以9*L/gcd(8,L)还是会互质】

    所以由性质1,(10^x)-1是q的倍数。

    所以(10^x)-1=0  (mod q)

      (10^x)=1  (mod q)

    性质2:欧拉定理。对于正整数a,n,若gcd(a,q)=1,则有a^phi(q)=1  (mod q)    【其中phi是欧拉函数】

    这个式子是不是和上面很像呢~

    所以若gcd(10,q)=1说明有解,否则无解

    对于有解的情况,x=phi(q)就是一个解,但不一定是最小解。actually,0---phi(q)中还可能存在解。

    性质3:因为后面有mod n,而余数都是有循环节的。(即一个循环周期的长度,设为r)

    eg:如果有10^a=1  (mod q),那么10^(a+r)=1  (mod q)

    首先x=0是一个解【10^0=1  (mod q)】。而且已经确定phi(q)也是一个解了。所以phi(q)一定是这个循环节r的倍数。

    根据性质3,r肯定也是一个解。而且是最小的。

    所以只要枚举phi(q)的约数,找出其中最小的满足条件的即可。

    -----------------------接下来是满满的黑科技orz----------------------

    Q1:本题数据很大,求gcd的过程会TLE肿么办

    A1:因为gcd里面有一个数字是固定的,所以可以用一下黑科技

            //q=9*N/gcd(8,N);
            q=9*N;
            for (int i=0;i<3;i++)
                if (q%2==0)
                    q=q/2;
                else break;
    要求的是q/gcd(8,N)
    而8分解质因数之后是2^3,也就是说带8的gcd里面最多也只可能有3个2。所以直接把这3个2能除掉的都除掉就行了
            //if (gcd(10,q)!=1)    ans=0;
            if  ((q%2==0)||(q%5==0))
                ans=0;
    10的质因子只有2和5。如果q是2或5的倍数,就说明q和10不互质。

    Q2:求快速幂取模(10^x)%q的时候,数据超了long long的范围,会出错

    A2:这样:

    LL func(LL a,LL b,LL c)     //a*b%c
    {
        long long ret = 0;
        while (b)
        {
            if (b & 1)
                ret = (ret + a) % c;
            a = 2 * a % c;
            b >>= 1;
        }
        return ret;
    }
    
    LL pow_mod(LL a,LL b,LL MOD)
    {
        if (a==1)   return 1;
        LL t=a%MOD,ans=1;
        while(b)
        {
            if (b&1)
                ans=func(ans,t,MOD);
            t=func(t,t,MOD);
            b>>=1;
        }
        return ans;
    }

    其实我也没看懂func是个什么鬼。。。。【逃

    AC Code:

      1 #include <iostream>
      2 #include <cstdio>
      3 using namespace std;
      4 #define LL long long
      5 #define MAXL 1000
      6 
      7 LL TC=0;
      8 LL N,MOD,TM,q,ans;
      9 int phi[MAXL+5];
     10 
     11 int gcd(int a,int b)                   //辗转相除法,返回gcd(a,b)
     12 {
     13     if (b==0) return a;
     14     return gcd(b,a%b);
     15 }
     16 
     17 long long euler(long long n)
     18 {
     19     long long ret = n;
     20     for (long long i = 2; i * i <= n; i++)
     21         if (n % i == 0)
     22         {
     23             ret = ret / i * (i - 1);
     24             while (n % i == 0)
     25                 n /= i;
     26         }
     27     if (n > 1)
     28         ret = ret / n * (n - 1);
     29     return ret;
     30 }
     31 
     32 
     33 /*
     34 LL pow_mod(LL a,LL b,LL MOD)
     35 {
     36     if (a==1)   return 1;
     37     LL t=a%MOD,ans=1;
     38     while(b)
     39     {
     40         if (b&1)
     41             ans=ans*t%MOD;
     42         t=t*t%MOD;
     43         b>>=1;
     44     }
     45     return ans;
     46 }
     47 */
     48 
     49 LL func(LL a,LL b,LL c)     //a*b%c
     50 {
     51     long long ret = 0;
     52     while (b)
     53     {
     54         if (b & 1)
     55             ret = (ret + a) % c;
     56         a = 2 * a % c;
     57         b >>= 1;
     58     }
     59     return ret;
     60 }
     61 
     62 LL pow_mod(LL a,LL b,LL MOD)
     63 {
     64     if (a==1)   return 1;
     65     LL t=a%MOD,ans=1;
     66     while(b)
     67     {
     68         if (b&1)
     69             ans=func(ans,t,MOD);
     70         t=func(t,t,MOD);
     71         b>>=1;
     72     }
     73     return ans;
     74 }
     75 
     76 int main()
     77 {
     78     //calc_phi(MAXL);
     79     while (~scanf("%I64d",&N))
     80     {
     81         TC++;
     82         if (N==0)   break;
     83         //q=9*N/gcd(8,N);
     84         q=9*N;
     85         for (int i=0;i<3;i++)
     86             if (q%2==0)
     87                 q=q/2;
     88             else break;
     89 
     90         TM=euler(q);    //tm=phi[q];
     91         ans=TM;
     92         //if (gcd(10,q)!=1)
     93         if  ((q%2==0)||(q%5==0))
     94             ans=0;
     95         else
     96         {
     97             for (LL i=1; i*i<=TM; i++)
     98                 if (TM%i==0)
     99                 {
    100                     LL t1=i,t2=TM/i;
    101                     LL M1=pow_mod(10,t1,q);
    102                     LL M2=pow_mod(10,t2,q);
    103                     //cout<<t1<<" "<<M1<<endl<<t2<<" "<<M2<<endl;
    104                     if ((M1==1)&&(t1<ans))
    105                         ans=t1;
    106                     if ((M2==1)&&(t2<ans))
    107                         ans=t2;
    108                 }
    109         }
    110         printf("Case %d: ",TC);
    111         cout<<ans<<endl;
    112     }
    113 }
    114 
    115 
    116 
    117 /*
    118 LL len,tmp,N;
    119 int TC=0;
    120 bool ok;
    121 
    122 int main()
    123 {
    124     while(~scanf("%I64d",&N))
    125     {
    126         TC++;
    127         if (N==0)   break;
    128         tmp=8;
    129         len=1;
    130         ok=false;
    131         if (tmp%N==0)   ok=true;
    132         while ((!ok)&&(len<=MAXL))
    133         {
    134             tmp=tmp*10+8;
    135             len++;
    136             if (tmp%N==0)
    137                 ok=true;
    138         }
    139         if (ok)
    140             printf("Case %d: %I64d
    ",TC,len);
    141         else
    142             printf("Case %d: 0
    ",TC);
    143     }
    144 
    145     return 0;
    146 }
    147 */
    View Code

    Reference:

    http://www.cnblogs.com/rainydays/archive/2012/11/05/2754760.html

    http://blog.csdn.net/yhrun/article/details/6908470

  • 相关阅读:
    bootstrap-table 切换页码保留勾选的checkbox
    vsftp服务器同步文件
    MySQL5.7 主从复制配置
    VMware NAT模式下设置网络
    在Jsp中调用静态资源,路径配置问题,jsp获取路径的一些方法
    centos7.3安装配置vsftp
    Linux安装配置Nginx
    jsp登录页面,展示错误信息,刷新页面后错误依然存在解决方案
    linux中使用Jmeter压测总结
    常规测试方法
  • 原文地址:https://www.cnblogs.com/pdev/p/4316596.html
Copyright © 2011-2022 走看看