• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            poj 3696 The Luckiest number

               這個題很奇葩了。題意是給出個數字L,假如存在一個數K使得L*K = 888...,求888...的最小長度,如果不存在這樣的K,那么輸出0。
            我是什么思路也沒有了,拖了幾天了,數論搞死我了,只能找答案了。
               我看到個比較靠譜的推法。首先,888...=111...*8=(10^0+10^1+...+10^m-1)*8=(10^m - 1)/9*8,PS:m代表888...的長度。
            好吧,終于化成指數了,現在有8*(10^m-1)/9=K*L,最小的m就是我們要求的答案啦。

               方式1:
               => 8 * (10^m-1) = 9 * k * L
               => 8/d*(10^m-1)=9*k*L/d,d=gcd(8,9L)
               => 10^m-1 = 0 % 9 * L / gcd(8, 9L) = 0 % 9*L/gcd(8,L),(由于gcd(8/d,9L/d)=1,那么10^m-1必然是9*L/d的倍數了)。
               => 10^m = 1 % 9 * L / gcd(8,L) 
               方式2:
               => 8*(10^m-1)/9 = 0 % L
               => 8*(10^m-1) = 0 % 9*L(這步的推出,比如x/9 = k*n,那么x=9*k*n了,顯然成立)
               => 10^m-1 = 0 % 9*L/gcd(9*L,8),假如,d = gcd(9*L,8),那么有8/d*(10^m-1)=k*9*L/d,因為8/d不可能是9  *L / d
            的倍數,所以10^m-1必定是9*L/d的倍數,所以10^m-1 = 0 % 9*L/gcd(9*L,8)),=>,10^m - 1 = 0 % 9 * L / gcd(L, 8),
            (因為gcd(9,8)=1)。
               => 10^m = 1 % 9*L/gcd(8,L)  

               至此,2種方式都推出了,10^m = 1 % 9*L/gcd(8,L) 。
               那么怎么解答這個問題了,這個就用到了歐拉定理了。令p = 9 * L / gcd(8,L),那么有10^m = 1 % p。由歐拉定理知,Z*p中所有的
            數字a均滿足a^euler(p) = 1 % p。那么,10只要是p的乘法群中就肯定有解了。如果,10不在Z*p中了,肯定是無解的。證明如下:
            由a^x = 1%p,可以得到a^(x-1)*a=1%p,要a^(x-1)存在,那么gcd(a,p)|1,那么gcd(a,p)必須是1。
               綜上所述,要滿足式子a^m=1%p,必須gcd(p,a)=1,即a必須是p的乘法群中的數字。
               現在的問題是求最小的m,由歐拉定理知道a^euler(p)=1%p,m再大就開始循環了。但是m可能會更小。比如,我們現在知道最小的m
            是min,那么有a^min=1%p,因為要滿足a^euler(p)=1%p,那么a^euler(p)肯定能變換成(a^min)^k,至于k是多少就不知道了,當然
            也可以求出來。那么min就是euler(p)的一個因子,而且是最小的一個滿足a^min=1%p的因子了。
               現在就可以通過枚舉euler(p)的因子,找到最小的因子min滿足式子a^min = 1 % p就能解決本問題了。
               注意求a^m%p肯定是通過算法導論上面那種方法的,O(32)或者O(64)的復雜度,還有a*b%m也需要自己模擬,因為可能a*b就溢出了。
               代碼如下,貌似代碼還可以通過其它的改進加快速度。

            #include <stdio.h>
            #include <math.h>
            #include <algorithm>
            #include <string.h>
            using namespace std;
            typedef long long INT;

            //10^m = 1 % (9*L / gcd(8, L)),求最小m
            //p = 9 * L / gcd(8,L)
            //gcd(p,10) != 1則p有2或者5的因子,2^m=1%p或者
            //5^m=1%p無解,原式無解
            //if(p)素數,m=euler(p) = p - 1
            //否則,m一定是euler(p)的最小滿足等式的因子
            //因為(10^m)^n = 10^euler(p) = 1%p
            INT gcd(INT a, INT b)
            {
                if (a < b)swap(a, b);
                while (b)
                {
                    INT t = a;
                    a = b;
                    b = t % b;
                }
                return a;
            }

            INT Euler(INT nN)
            {
                INT nAns = 1;
                INT nMax = sqrt((double)nN) + 1;
                for (INT i = 2; i <= nMax; ++i)
                {
                    if (nN % i == 0)
                    {
                        nAns *= i - 1;
                        nN /= i;
                        while (nN % i == 0)
                        {
                            nAns *= i;
                            nN /= i;
                        }
                    }
                }
                if (nN != 1)nAns *= nN - 1;
                return nAns;
            }

            INT MultMod(INT a, INT b, INT mod)
            {
                INT ans = 0;
                while (b)
                {
                    if (b & 1)
                    {
                        ans = (ans + a) % mod;
                    }
                    a = (2 * a) % mod;
                    b >>= 1;
                }
                return ans;
            }

            INT ExpMod(INT base, INT exp, INT mod)
            {
                INT ans = 1;
                base %= mod;
                while (exp)
                {
                    if (exp & 1)
                    {
                        ans = MultMod(ans, base, mod);
                    }
                    base = MultMod(basebase, mod);
                    exp >>= 1;
                }
                return ans % mod;
            }

            INT GetAns(INT p)
            {
                INT u = Euler(p);
                INT nMax = sqrt((double)u) + 1;
                INT nAns = u;
                for (INT i = 1; i <= nMax; ++i)
                {
                    if (u % i == 0)
                    {
                        if (ExpMod(10, i, p) == 1)
                        {
                            nAns = i;
                            break;
                        }
                        if (ExpMod(10, u / i, p) == 1)
                        {
                            nAns = min(nAns, u / i);
                        }
                    }
                }
                return nAns;
            }

            int main()
            {
                INT nL;
                INT nCase = 1;
                
                while (scanf("%I64d", &nL), nL)
                {
                    INT p = 9 * nL / gcd(nL, 8);
                    if (gcd(p, 10) != 1)
                    {
                        printf("Case %I64d: 0\n", nCase++);
                        continue;
                    }
                    printf("Case %I64d: %I64d\n", nCase++, GetAns(p));
                }
                
                return 0;
            }

            posted on 2012-08-02 13:06 yx 閱讀(1103) 評論(3)  編輯 收藏 引用 所屬分類: 數論

            評論

            # re: poj 3696 The Luckiest number 2012-08-04 13:06 小柯

            是不是弄復雜了?直接模擬就可以解決了吧  回復  更多評論   

            # re: poj 3696 The Luckiest number 2013-06-25 08:39 nike0good

            數量很大,必然超時@小柯
              回復  更多評論   

            <2012年9月>
            2627282930311
            2345678
            9101112131415
            16171819202122
            23242526272829
            30123456

            導航

            統計

            公告

            常用鏈接

            留言簿(3)

            隨筆分類

            隨筆檔案

            me

            好友

            同學

            網友

            搜索

            最新評論

            閱讀排行榜

            評論排行榜

            久久精品国产99久久香蕉| 欧美777精品久久久久网| 久久国产亚洲精品| 久久影院综合精品| 久久国产亚洲高清观看| 久久精品中文字幕第23页| 伊人久久久AV老熟妇色| 91精品久久久久久无码| 久久只有这里有精品4| 久久国产精品久久久| 国内精品伊人久久久影院| 97久久精品人人做人人爽| 久久久亚洲裙底偷窥综合| 国产精品嫩草影院久久| 精品国产VA久久久久久久冰| 亚洲国产成人久久笫一页| 欧美激情精品久久久久| 久久精品天天中文字幕人妻| 要久久爱在线免费观看| 国产精品九九久久免费视频| 久久99热国产这有精品| 天天爽天天狠久久久综合麻豆| 久久久久久亚洲精品不卡 | 色8久久人人97超碰香蕉987| 久久久久亚洲AV综合波多野结衣| 久久99热精品| 国内精品久久久久影院一蜜桃| 亚洲精品99久久久久中文字幕| 久久国产热这里只有精品| 91精品观看91久久久久久| 久久国产成人精品麻豆| 俺来也俺去啦久久综合网| 日韩乱码人妻无码中文字幕久久| 久久人妻少妇嫩草AV蜜桃| 国内精品久久久久影院薰衣草 | 久久99毛片免费观看不卡| 国内精品久久久久伊人av| www.久久热| 国产免费久久精品99久久| 久久无码精品一区二区三区| 久久亚洲精品国产精品婷婷|