??xml version="1.0" encoding="utf-8" standalone="yes"?>久久国产成人,久久久久亚洲AV无码专区体验,99久久超碰中文字幕伊人http://www.shnenglu.com/csu-yx-2013/category/19722.htmlAlgorithm Study And So Onzh-cnFri, 13 Sep 2013 11:18:10 GMTFri, 13 Sep 2013 11:18:10 GMT60poj 1006 Biorhythms 中国剩余定理http://www.shnenglu.com/csu-yx-2013/archive/2012/10/03/192726.htmlyxyxWed, 03 Oct 2012 15:11:00 GMThttp://www.shnenglu.com/csu-yx-2013/archive/2012/10/03/192726.htmlhttp://www.shnenglu.com/csu-yx-2013/comments/192726.htmlhttp://www.shnenglu.com/csu-yx-2013/archive/2012/10/03/192726.html#Feedback0http://www.shnenglu.com/csu-yx-2013/comments/commentRss/192726.htmlhttp://www.shnenglu.com/csu-yx-2013/services/trackbacks/192726.html   q题主要是可以用中国剩余定理来做?br />   Ҏ题意可以抽象L模型。给Z个数A,B,C分别是模23,28,33后的余数Q求最的数字
使得其模23,28,33分别为A,B,CQƈ且要大于l定的数字D?br />   中国剩余定理很好的解决了q种余数问题。o模数为Ni,余数为Ai,设Mi = N1*N2*...*Ni-1*Ni+1*...*NnQ?br />那么{案一定满_Ş式ans = ΣAi*Mi*(Mi对Ni的乘法? % N?N为所有Ni的乘U??br />   很明显,׃ans的第iҎMi因子Q所以模N1-Ni-1和Ni+1-Nn肯定?Q而Ai*Mi*(Mi对Ni的乘法? %Ni
是Ai。这样就满了要求?br />   代码如下Q?br />
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <vector>
using namespace std;

int Egcd(int nN, int nM, int& nX, int& nY)
{
    if (nM == 0)
    {
        nX = 1, nY = 0;
        return nN;
    }
    int nRet = Egcd(nM, nN % nM, nX, nY);
    int nT = nX;
    nX = nY;
    nY = nT - (nN / nM) * nY;
    return nRet;
}

int main()
{
    int nA, nB, nC, nD;
    int nDays = 21252;
    int nCase = 1;
    
    while (scanf("%d%d%d%d", &nA, &nB, &nC, &nD),
           nA != -1 || nB != -1 || nC != -1 || nD != -1)
    {
        int nFirst = 0;
        nA %= 23;
        nB %= 28;
        nC %= 33;
        int nM1= 28 * 33, nM2 = 23 * 33, nM3 = 23 * 28;
        int nN1, nN2, nN3, nTemp;
        Egcd(23, nM1, nTemp, nN1);
        Egcd(28, nM2, nTemp, nN2);
        Egcd(33, nM3, nTemp, nN3);
        nFirst = (nA * nM1 * nN1 + nB * nM2 * nN2 + nC * nM3 * nN3) % nDays;
        while (nFirst <= nD)nFirst += nDays;
        printf("Case %d: the next triple peak occurs in %d days.\n",
               nCase++, nFirst - nD);
    }
    
    return 0;
}


yx 2012-10-03 23:11 发表评论
]]>
poj 1811 Prime Test 数论 素数试http://www.shnenglu.com/csu-yx-2013/archive/2012/09/24/191819.htmlyxyxMon, 24 Sep 2012 04:56:00 GMThttp://www.shnenglu.com/csu-yx-2013/archive/2012/09/24/191819.htmlhttp://www.shnenglu.com/csu-yx-2013/comments/191819.htmlhttp://www.shnenglu.com/csu-yx-2013/archive/2012/09/24/191819.html#Feedback0http://www.shnenglu.com/csu-yx-2013/comments/commentRss/191819.htmlhttp://www.shnenglu.com/csu-yx-2013/services/trackbacks/191819.html
#include <stdio.h>
#include <time.h>
#include <math.h>
#include <stdlib.h>
#include <algorithm>
using namespace std;
typedef unsigned long long LL;
#define MAX (5000000)
bool bPrime[MAX];
void InitPrime()
{
    int nMax = sqrt((double)MAX) + 1;
    bPrime[0] = bPrime[1] = true;
    for (int i = 2; i <= nMax; ++i)
    {
        if (!bPrime[i])
        {
            for (int j = 2 * i; j < MAX; j += i)
            {
                bPrime[j] = true;
            }
        }
    }
}
LL multAndMod(LL a, LL b, LL n)
{
    LL tmp = 0;
    while (b)
    {
        if(b & 1)
        {
            tmp = (tmp + a) % n;
        }
        a = (a << 1) % n;
        b >>= 1;
    }
    return tmp;
}
//计算a^u%n
LL ModExp(LL a, LL u, LL n)
{
    LL d = 1;
    a %= n;
    while (u)
    {
        if (u & 1)
        {
            d = multAndMod(d, a, n);
        }
        a = multAndMod(a, a, n);
        u >>= 1;
    }
    return d % n;
}
//判断nN是不是合?/div>
bool Witness(LL a, LL nN)
{
    LL u = nN - 1, t = 0;//nN-1表示为u*2^t
    while (u % 2 == 0)
    {
        t++;
        u >>= 1;
    }
    LL x0 = ModExp(a, u, nN);//x是a^u
    LL x1;
    for (int i = 1; i <= t; ++i)
    {
        x1 = multAndMod(x0, x0, nN);
        if (x1 == 1 && x0 != nN - 1 && x0 != 1)
        {
            return true;
        }
        x0 = x1;
    }
    if (x1 != 1)
    {
        return true;
    }
    return false;
}
//素数试
bool MillerRabin(LL nN)
{
    //if (nN < MAX)return !bPrime[nN];
    const int TIME = 10;
    for (int i = 0; i < TIME; ++i)
    {
        LL a = rand() % (nN - 1) + 1;
        if (Witness(a, nN))
        {
            return false;
        }
    }
    return true;
}
LL gcd(LL a, LL b)
{
    if (a < b)swap(a, b);
    while (b)
    {
        LL t = a;
        a = b;
        b = t % b;
    }
    return a;
}
//启发式寻找nN的因?/div>
LL PollardRho(LL n, LL c)
{
    LL i = 1, t = 2;
    LL x, y;
    LL ans;
    srand(time(NULL));  
    y = x = rand() % n;
    while(1)
    {
        i++;
        x = (multAndMod(x, x, n) + c) % n;
        ans = gcd(y - x, n);
        if(ans > 1 && ans < n)
            return ans;
        if(x == y)
            return n;
        if(t == i)
        {
            y = x;
            t <<= 1;
        }
    }
}
LL FindMin(LL nN, LL c)
{
    //printf("nN:%I64u\n", nN);
    if (MillerRabin(nN) || nN <= 1)
    {
        return nN;
    }
    LL p = nN;
    while (p >= nN) p = PollardRho(p, c--);
    if (p > 1)
        p = FindMin(p, c);//分解p的最因?/div>
    if (p < nN)
    {
        LL q = nN / p;
        q = FindMin(q, c);//扑ֈq的最因?/div>
        p = min(p, q);
    }
    return p;
}
int main()
{
    int nTest;
    srand(time(NULL));
    //InitPrime();
    scanf("%d", &nTest);
    while (nTest--)
    {
        LL nN;
        scanf("%I64u", &nN);
        if (nN > 2 && nN % 2 == 0)
        {
            printf("2\n");
        }
        else if (nN == 2 || MillerRabin(nN))
        {
            printf("Prime\n");
        }
        else
        {
            printf("%I64u\n", FindMin(nN, 181));
        }
    }
    return 0;
}


yx 2012-09-24 12:56 发表评论
]]>hdu 4294 Multiple 数论 + bfshttp://www.shnenglu.com/csu-yx-2013/archive/2012/09/18/191097.htmlyxyxTue, 18 Sep 2012 05:27:00 GMThttp://www.shnenglu.com/csu-yx-2013/archive/2012/09/18/191097.htmlhttp://www.shnenglu.com/csu-yx-2013/comments/191097.htmlhttp://www.shnenglu.com/csu-yx-2013/archive/2012/09/18/191097.html#Feedback0http://www.shnenglu.com/csu-yx-2013/comments/commentRss/191097.htmlhttp://www.shnenglu.com/csu-yx-2013/services/trackbacks/191097.html   题意是给出N,KQ求MQ得M是N的正倍数Q而且M用Kq制表示后所需要的不同数字(0,1,2,3,...,k-1)最,如果有多l?br />q样的情况,求出最的M?br />   很数学的题意。用C一个结论,是L数字的正倍数均可以用不超q?个不同数字的数得到?br />   证明如下Q?br />   L数M % N d有NU结果,假如有N+1个不同的MQ那么肯定有2个M对N取模后的l果是相同,q个是所谓鸽巢原理?br />那么Q我取a,aa,aaa,...,aaaaaaaaaa....QdN+1个,同样满上面的结论。那么我取那2个对N取模相同的数字相减得?br />数字aaaaa...000....Q这个数字肯定是N的倍数?br />   l合上面的证明,只能得到2个数字肯定能表示N的倍数。但是不能说形式是aaaaa...000....?br />
   Cq里我还是一Ҏ\都没有,一炚w不知道怎么搜烦。。?br />   想了1个多时Q无头AQ问q了q题的同学,q是无头l。看解题报告Q他们的代码写得太牛了,完全看不懂,无头l?br />也许也是我对bfs理解太浅Q才看不懂他们的搜烦代码。而且Q我q可以搜索的地方都没有找刎ͼ都不知道搜什么了?br />   想了好久Q昨天吃饭的时候,l于发现可以对余数进行搜索?br />   对于L的NQ其余数是范围是[0, N -1]。这个其实就可以代表状态了Q或者代表bfs中的点了。从当前余数转移到其?br />余数的是MOD * K +  A 或?MOD * K + BQ如果要转移到得余数以前没被搜过Q那可以{U过厅R这个刚好就是一?br />优化了。也可以看成是子问题了。但是,dfs完全不行。刚开始用dfsQ绝对的时?br />   用dfs也是我对思\理解不深Qoq认q。。。后面发玎ͼq题完全和bfsd。[0, N -1]刚好代表N个点Q我要通过
从外面的一个点Q最短的遍历到点0Q可以bfs或者最短\法。这题我觉得q有个难点就是保存答案,因ؓ{案最长的长度
可能是N(N<=10000)Q所以把{案直接攑ֈ节点里面肯定不行的。但是,我还仔细看过法D。因此想C可以利用bfs
搜烦出来的那颗树或者最短\法跑出来的那颗树,从目标节炚w序L{案Q找到出发节点之后,再把{案reverse一下就行了?br />   q题q得注意0不能是N的倍数Q所以注意bfs(0,i)q种情况的处理?br />
   代码如下Q?br />
#include <stdio.h>
#include <string.h>
#include <queue>
#include <algorithm>
using namespace std;

const int MAX_N = 10010;
int nOut[MAX_N];
int nOLen;
int nAns[MAX_N];
int nALen;
bool bMod[MAX_N];
int nFather[MAX_N];
int nChoose[MAX_N];
int nN;
int nK;
bool bFind;

int Cmp(int* A, int nLA, int* B, int nLB)
{
    if (nLA != nLB)
    {
        return nLA - nLB;
    }
    for (int i = 0; i < nLA; ++i)
    {
        if (A[i] != B[i])
        {
            return A[i] - B[i];
        }
    }
    return 0;
}

void Bfs(int nA, int nB)
{
    memset(bMod, falsesizeof(bMod));
    queue<int> que;
    que.push(0);
    int nTemp;
    bool bFirst = true;
    bFind = false;
    
    if (nA > nB)swap(nA, nB);
    //printf("nA:%d, nB:%d\n", nA, nB);
    while (!que.empty())
    {
        //printf("nMod:%d\n", que.front());
        int nMod = que.front();
        que.pop();
        if (nMod == 0)
        {
            if (bFirst)bFirst = false;
            else
            {
                bFind = true;
                break;
            }
        }
        
        nTemp = (nMod * nK + nA) % nN;
        if (!(nMod == 0 && nA == 0) && !bMod[nTemp])
        {
            nFather[nTemp] = nMod;
            nChoose[nTemp] = nA;
            que.push(nTemp);
            bMod[nTemp] = true;
            //printf("nTemp:%d\n", nTemp);
        }
        if (nA == nB)continue;
        nTemp = (nMod * nK + nB) % nN;
        if (!bMod[nTemp])
        {
            nFather[nTemp] = nMod;
            nChoose[nTemp] = nB;
            que.push(nTemp);
            bMod[nTemp] = true;
            //printf("nTemp:%d\n", nTemp);
        }
    }
    
    if (bFind)
    {
        int nF = 0;
        nALen = 0;
        do
        {
            nAns[nALen++] = nChoose[nF];
            nF = nFather[nF];
        } while (nF);
        reverse(nAns, nAns + nALen);
    }
}

int main()
{
    while (scanf("%d%d", &nN, &nK) == 2)
    {
        bool bOk = false;
        nOLen = 0;
        for (int i = 1; i < nK; ++i)
        {
            Bfs(i, i);
            if (bFind)
            {
                if (nOLen == 0 || Cmp(nOut, nOLen, nAns, nALen) > 0)
                {
                    nOLen = nALen;
                    memcpy(nOut, nAns, sizeof(int) * nALen);
                }
                bOk = true;
            }
        }
        if (!bOk)
            for (int i = 0; i < nK; ++i)
            {
                for (int j = i + 1; j < nK; ++j)
                {
                    Bfs(i, j);
                    if (bFind)
                    {
                        if (nOLen == 0 || Cmp(nOut, nOLen, nAns, nALen) > 0)
                        {
                            nOLen = nALen;
                            memcpy(nOut, nAns, sizeof(int) * nALen);
                        }
                    }
                }
            }
        for (int k = 0; k < nOLen; ++k)
        {
            printf("%d", nOut[k]);
        }
        printf("\n");
    }

    return 0;
}


yx 2012-09-18 13:27 发表评论
]]>
poj 3243 Clever Yhttp://www.shnenglu.com/csu-yx-2013/archive/2012/08/05/186351.htmlyxyxSun, 05 Aug 2012 07:09:00 GMThttp://www.shnenglu.com/csu-yx-2013/archive/2012/08/05/186351.htmlhttp://www.shnenglu.com/csu-yx-2013/comments/186351.htmlhttp://www.shnenglu.com/csu-yx-2013/archive/2012/08/05/186351.html#Feedback0http://www.shnenglu.com/csu-yx-2013/comments/commentRss/186351.htmlhttp://www.shnenglu.com/csu-yx-2013/services/trackbacks/186351.htmlXY mod Z = KQ给出XQZQKQ求Y?br />   当Z是素数的时候直接用baby-step法卛_了。但是,模数不是素数的情冉|么办了?br />   方程a^X = b % cQ可以进行一pd的{化。假设d = gcd(a,c)Q由a^(x-1)*a = b % cQ知道a^(x-1)要存在必L?br />gcd(a,c)|bQ如果满个条Ӟ那么我们可以在方E?边同旉以dQ方E是不变的。因为a^x = b + k * cQ再除以公约?br />dQ得到方Ea^(x-1)*a/d = b / d + k * c / d。根据以上推论,我们可以不断的除以dQ直到gcd(a,c)=1?br />   假设我们除了kơ,那么方程转化为a^(x-k) * a^k/d^k = b / d^k + k * c / d^k。od = a^k/d^kQb' = b / d^kQ?br />c' = c / d^kQx' = x - kQ方E{化ؓa^x' * d = b' % c'Q得到a^x' = b' * d^-1 % c'?br />   现在直接用baby-step解方Ea^x' = b' * (d^-1) % c'卛_。注意到x=x'+kQ如果存在x于k的解Q那么x'于0Q但?br />由baby-step是不会求负的ơ数的,所以需要先枚D一下是否存在小于k的解Q由于输入的数据不会过10^9的,假设k不超q?0
q行枚D卛_了?br />
   代码如下Q?br />
#include <stdio.h>
#include <math.h>
#include <algorithm>
using namespace std;
typedef long long INT;
#define MAX (1000000)
INT nData[MAX];
INT nKey[MAX];

INT HashPos(INT key)
{
    return ((unsigned)(key ^ 0xA5A5A5A5)) % MAX;
}

void HashAdd(INT key, INT data)
{
    INT nPos = HashPos(key);
    while (nData[nPos] != -1)
    {
        nPos = (nPos + 1) % MAX;
    }
    nData[nPos] = data;
    nKey[nPos] = key;
}

INT HashQuery(INT key)
{
    INT nPos = HashPos(key);
    while (nData[nPos] != -1)
    {
        if (nKey[nPos] == key)
        {
            return nData[nPos];
        }
        nPos = (nPos + 1) % MAX;
    }
    
    return -1;
}

INT MultMod(INT nA, INT nB, INT nC)
{
    INT nAns = 0;
    while (nB)
    {
        if (nB & 1)
        {
            nAns = (nAns + nA) % nC;
        }
        nA = (2 * nA) % nC;
        nB >>= 1;
    }
    return nAns;
}

INT PowerMod(INT nA, INT nX, INT nC)
{
    INT nAns = 1;
    nA %= nC;
    while (nX)
    {
        if (nX & 1)
        {
            nAns = MultMod(nAns, nA, nC); 
        }
        nA = MultMod(nA, nA, nC);
        nX >>= 1;
    }
    return nAns;
}

INT gcd(INT nA, INT nB)
{
    if (nA < nB)swap(nA, nB);
    while (nB)
    {
        INT nT = nA;
        nA = nB;
        nB = nT % nB;
    }
    return nA;
}
//d = nA * nX + nB * nY(nA > nB, nA是模?
INT egcd(INT nA, INT nB, INT& nX, INT& nY)
{
    if (nA < nB)swap(nA, nB);
    if (nB == 0)
    {
        nX = 1;
        nY = 0;
        return nA;
    }
    INT nRet = egcd(nB, nA % nB, nX, nY);
    INT nT = nX;
    nX = nY;
    nY = nT - (nA / nB) * nY;
    return nRet;
}

INT GetAns(INT nA, INT nB, INT nC)
{
    if (nC == 0)return -1;
    //先枚?-50,扩展baby-step的过E可能会漏掉q些?/span>
    INT nTemp = 1;
    nB %= nC;
    for (INT i = 0; i <= 50; ++i)
    {
        if (nTemp == nB)
        {
            return i;
        }
        nTemp = MultMod(nTemp, nA, nC);
    }
    
    //如果nC不是素数,那么方程nA^x = nB + k*nC
    
//可以不到除以gcd(nC,nA)
    
//如果gcd(nC,nA)|nB不成?方程无解Q?br />    //q个由a*x=b%c有解必须满gcd(a,c)|b一?/span>
    INT d;
    INT nD = 1;//nD最后是A^k?k是nC中因子d的次?/span>
    INT k = 0;
    while ((d = gcd(nC, nA)) != 1)
    {
        k++;
        nC /= d;
        if (nB % d)return -1;
        nB /= d;
        nD = MultMod(nD, nA / d, nC);
    }
    //现在方程转化为nA^(x-k) * nA^k/d^k = nB/d^k % nC/d^k
    
//其实是方程2侧除以d^kơ而已,q样的做法与原方E是{h?br />    //令nD = nA^k/d^k,则nA^x'*nD = nB' % nC',
    
//解该方程,那么x=x'+k
    
//注意,如果x<k,那么x'?baby-step无法求出,故在函数开头进行枚?/span>
    memset(nKey, -1, sizeof(nKey));
    memset(nData, -1, sizeof(nData));
    INT nM = ceil(sqrt(1.0 * nC));
    nTemp = 1;
    for (INT j = 0; j <= nM; ++j)
    {
        HashAdd(nTemp, j);
        nTemp = MultMod(nTemp, nA, nC);
    }
    INT nK = PowerMod(nA, nM, nC);
    for (int i = 0; i <= nM; ++i)
    {
        INT x, y;
        egcd(nC, nD, x, y);//y = nD^-1,nD = nD*(nA^m)^i
        y = (y + nC) % nC;//q句话是必须?y很可能就是负?/span>
        INT nR = MultMod(y, nB, nC);//nR=nB*nD^-1
        int j = HashQuery(nR);
        if (j != -1)
        {
            return nM * i + j + k;
        }
        
        nD = MultMod(nD, nK, nC);
    }
    return -1;
}

int main()
{
    INT nA, nB, nC;
    
    while (scanf("%I64d%I64d%I64d", &nA, &nC, &nB), nA + nB + nC)
    {
        INT nAns = GetAns(nA, nB, nC);
        if (nAns == -1)
        {
            printf("No Solution\n");
        }
        else
        {
            printf("%I64d\n", nAns);
        }
    }
    
    return 0;
}


yx 2012-08-05 15:09 发表评论
]]>
poj 3696 The Luckiest numberhttp://www.shnenglu.com/csu-yx-2013/archive/2012/08/02/186027.htmlyxyxThu, 02 Aug 2012 05:06:00 GMThttp://www.shnenglu.com/csu-yx-2013/archive/2012/08/02/186027.htmlhttp://www.shnenglu.com/csu-yx-2013/comments/186027.htmlhttp://www.shnenglu.com/csu-yx-2013/archive/2012/08/02/186027.html#Feedback3http://www.shnenglu.com/csu-yx-2013/comments/commentRss/186027.htmlhttp://www.shnenglu.com/csu-yx-2013/services/trackbacks/186027.html我是什么思\也没有了Q拖了几天了Q数论搞L了,只能扄案了?br />   我看C比较靠谱的推法。首先,888...=111...*8=(10^0+10^1+...+10^m-1)*8=(10^m - 1)/9*8QPSQm代表888...的长度?br />好吧Q终于化成指CQ现在有8*(10^m-1)/9=K*LQ最的m是我们要求的答案啦?br />
   方式1Q?br />   => 8 * (10^m-1) = 9 * k * L
   => 8/d*(10^m-1)=9*k*L/dQd=gcd(8,9L)
   => 10^m-1 = 0 % 9 * L / gcd(8, 9L) = 0 % 9*L/gcd(8,L)Q?׃gcd(8/d,9L/d)=1Q那?0^m-1必然?*L/d的倍数??br />   => 10^m = 1 % 9 * L / gcd(8,L) 
   方式2Q?br />   => 8*(10^m-1)/9 = 0 % L
   => 8*(10^m-1) = 0 % 9*L(q步的推出,比如x/9 = k*nQ那么x=9*k*n了,昄成立)
   => 10^m-1 = 0 % 9*L/gcd(9*L,8)Q假如,d = gcd(9*L,8)Q那么有8/d*(10^m-1)=k*9*L/dQ因?/d不可能是9  *L / d
的倍数Q所?strong>10^m-1必定?*L/d的倍数Q所?0^m-1 = 0 % 9*L/gcd(9*L,8))Q?>Q?0^m - 1 = 0 % 9 * L / gcd(L, 8),
(因ؓgcd(9,8)=1)?br />   => 10^m = 1 % 9*L/gcd(8,L)  

   xQ?U方式都推出了,10^m = 1 % 9*L/gcd(8,L) ?br />   那么怎么解答q个问题了,q个qCƧ拉定理了。op = 9 * L / gcd(8,L)Q那么有10^m = 1 % p。由Ƨ拉定理?Z*p中所有的
数字a均满a^euler(p) = 1 % p。那么,10只要是p的乘法群中就肯定有解了。如果,10不在Z*p中了Q肯定是无解的。证明如下:
由a^x = 1%pQ可以得到a^(x-1)*a=1%pQ要a^(x-1)存在Q那么gcd(a,p)|1Q那么gcd(a,p)必须??br />   lg所qͼ要满_?strong>a^m=1%pQ必gcd(p,a)=1Q即a必须是p的乘法群中的数字?br />   现在的问题是求最的mQ由Ƨ拉定理知道a^euler(p)=1%pQm再大开始@环了。但是m可能会更。比如,我们现在知道最的m
是minQ那么有a^min=1%pQ因满a^euler(p)=1%pQ那么a^euler(p)肯定能变换成(a^min)^k,至于k是多就不知道了Q当?br />也可以求出来。那么min是euler(p)的一个因子,而且是最的一个满a^min=1%p的因子了?br />   现在可以通过枚Deuler(p)的因子,扑ֈ最的因子min满式子a^min = 1 % pp解决本问题了?br />   注意求a^m%p肯定是通过法D上面那种Ҏ?O(32)或者O(64)的复杂度Q还有a*b%m也需要自己模拟,因ؓ可能a*b溢Z?br />   代码如下Q貌g码还可以通过其它的改q加快速度?br />
#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^m=1%p或?br />//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;
}


yx 2012-08-02 13:06 发表评论
]]>
poj 2480 Longge's problemhttp://www.shnenglu.com/csu-yx-2013/archive/2012/07/31/185736.htmlyxyxTue, 31 Jul 2012 03:47:00 GMThttp://www.shnenglu.com/csu-yx-2013/archive/2012/07/31/185736.htmlhttp://www.shnenglu.com/csu-yx-2013/comments/185736.htmlhttp://www.shnenglu.com/csu-yx-2013/archive/2012/07/31/185736.html#Feedback0http://www.shnenglu.com/csu-yx-2013/comments/commentRss/185736.htmlhttp://www.shnenglu.com/csu-yx-2013/services/trackbacks/185736.htmlΣgcd(i,n)(1<=i<=n)。感觉好奇葩的题目,数论的题实比较难想Q没看出跟欧拉函数有什么关pR?br />很纠l,没心情没旉l箋想了。看了discussionQ然后又L了下{案Q发现有个哥们也得非怸错,q了下思\了?br />   q个题的解法是枚举i(1<=i<=n)Q如果i|nQ那么答案加上euler(n/i)*i。其实ans = Σi*euler(n/i)(i<=i<=n而且i|n)?br />意思是?到n的所有数字iQ如果i是n的因子,那么计算i*euler(n/i)Q加入答案中Qeuler是欧拉函数的意思?br />   Z么是q样的了。比如,1到n中有m个数字和n拥有公共的最大因子iQ那么就需要把m*i加入{案中。问题是如何计算m的个数?br />因ؓgcd(m,n) = iQ可以得到gcd(m/i,n/i)=1Q那么m/i是n/i的乘法群中的数字了,那么一共存在euler(n/i)个m/i了,那么?br />可以推出m的个数就是euler(n/i)?br />   
代码如下:
#include <stdio.h>
#include <math.h>
#define MAX (6000000)
bool bPrime[MAX];

void InitPrime()
{
    int nMax = sqrt((double)MAX) + 1;
    bPrime[0] = bPrime[1] = true;
    for (int i = 2; i <= nMax; ++i)
    {
        if (!bPrime[i])
        {
            for (int j = 2 * i; j < MAX; j += i)
            {
                bPrime[j] = true;
            }
        }
    }
}

bool IsPrime(long long nN)
{
    if (nN < MAX)return !bPrime[nN];
    long long nMax = sqrt((double)nN) + 1;
    for (int i = 2; i <= nMax; ++i)
    {
        if (nN % i == 0)
        return false;
    }
    return true;
}

long long Euler(long long nN)
{
    long long nAns = 1;
    
    //printf("nN:%I64d,", nN);
    if (IsPrime(nN))nAns = nN - 1;
    else
    for (int i = 2; i <= nN; ++i)
    {
        if (nN % i == 0)
        {
            nAns *= i - 1;
            nN /= i;
            while (nN % i == 0)
            {
                nAns *= i;
                nN /= i;
            }
            if (IsPrime(nN))
            {
                nAns *= nN - 1;
                break;
            }
        }
    }
    
    //printf("nAns:%I64d\n", nAns);
    return nAns;
}

int main()
{
    long long nN;
    
    InitPrime();
    while (scanf("%I64d", &nN) == 1)
    {
        long long nAns = 0;
        long long nMax = sqrt((double)nN) + 1e-8;
        for (long long i = 1; i <= nMax; ++i)
        {
            if (nN % i == 0)
            {
                //printf("i:%I64d\n", i);
                nAns += i * Euler(nN / i);
                if (i * i != nN)
                nAns += (nN / i) * Euler(i);
            }
        }
        printf("%I64d\n", nAns);
    }
    
    return 0;
}



yx 2012-07-31 11:47 发表评论
]]>
poj 1284 Primitive Rootshttp://www.shnenglu.com/csu-yx-2013/archive/2012/07/30/185687.htmlyxyxMon, 30 Jul 2012 14:36:00 GMThttp://www.shnenglu.com/csu-yx-2013/archive/2012/07/30/185687.htmlhttp://www.shnenglu.com/csu-yx-2013/comments/185687.htmlhttp://www.shnenglu.com/csu-yx-2013/archive/2012/07/30/185687.html#Feedback0http://www.shnenglu.com/csu-yx-2013/comments/commentRss/185687.htmlhttp://www.shnenglu.com/csu-yx-2013/services/trackbacks/185687.html1<=x<n}。如果n是奇素数p(大于2的素?Q那么满g^j={1,2,...,p-1}?br />   q个题目要求求原根的个数。由贚w定理?对Q?<=x<pQ即Zp*中的数字Q都由x^(p-1) = 1 % p。从贚w定理可以看出Q?br />再往下计就开始@环了。那么有,x^i%p(1<=i<p) = {1, 2, 3,...,p-1},意思是能够生成Zp*中的所有数字?br />   Ҏ上面的那个式子可以得刎ͼx^i%(p-1)(1<=i<p) = {0, 1, 2,...,p-2}?如果由gcd(x,p-1) = 1,那么必然存在某个x^iQ?br />使得x^i*x = (p-1)%p?br />   因此可以得到Q原根的个数是p-1的乘法群中元素的个数Q也是Ƨ拉函数(p-1)?br />
代码如下Q?br />   
#include <stdio.h>
#include <math.h>
#define MAX (5000000)
bool bPrime[MAX];
void InitPrime()
{
    int nMax = sqrt((double)MAX) + 1;
    bPrime[0] = bPrime[1] = true;
    for (int i = 2; i <= nMax; ++i)
    {
        if (!bPrime[i])
        {
            for (int j = 2 * i; j < MAX; j += i)
            {
                bPrime[j] = true;
            }
        }
    }
}
bool IsPrime(int nN)
{
    if (nN < MAX)return !bPrime[nN];
    int nMax = sqrt((double)nN) + 1;
    for (int i = 2; i <= nMax; ++i)
    {
        if (nN % i == 0)
            return false;
    }
    return true;
}
int main()
{
    int nN;
    InitPrime();
    while (scanf("%d", &nN) == 1)
    {
        nN--;
        int nAns = 1;
        if (IsPrime(nN))
        {
            nAns = nN - 1;
        }
        else
        {
            for (int i = 2; i <= nN; ++i)
            {
                if (nN % i == 0)
                {
                    nAns *= i - 1;
                    nN /= i;
                    while (nN % i == 0)
                    {
                        nAns *= i;
                        nN /= i;
                    }
                    if (IsPrime(nN))
                    {
                        nAns *= nN - 1;
                        break;
                    }
                }
            }
        }
        printf("%d\n", nAns);
    }
    return 0;
}


yx 2012-07-30 22:36 发表评论
]]>
poj 2417 Discrete Logginghttp://www.shnenglu.com/csu-yx-2013/archive/2012/07/29/185562.htmlyxyxSun, 29 Jul 2012 11:38:00 GMThttp://www.shnenglu.com/csu-yx-2013/archive/2012/07/29/185562.htmlhttp://www.shnenglu.com/csu-yx-2013/comments/185562.htmlhttp://www.shnenglu.com/csu-yx-2013/archive/2012/07/29/185562.html#Feedback0http://www.shnenglu.com/csu-yx-2013/comments/commentRss/185562.htmlhttp://www.shnenglu.com/csu-yx-2013/services/trackbacks/185562.html   问题的意思是l定素数PQ给出方Ea^x = b % pQ注意有模的方程{式2辚w是取模数的意思。解q样的方E有一个固定的法Q?br />叫做baby-step法。但是,注意限定条g是p必须是素数?br />   下面的图描述了这个算法:


   意思很清楚Q就是假设x = i * m + jQ那么方E可以{化ؓb*(a^-m)^i  = a^j % p。先计算出右边的|存储在一张表里面Q?br />然后从小到大枚D左边的iQ?<=i<m)Q率先满等式的是最的解x?br />   poj上面q个题用map存储(a^j,j)对的时候会时Q改成hash表存储才能过Q额Q毕竟理论复杂度不是一个数量的。我的hash表是
开?个数l,一个键Q一个|用来怺验证Q槽冲突的话Q一直往后找位置。感觉这L做法没有铑ּhash复杂度^均的样子?br />   代码如下Q?br />
#include <stdio.h>
#include <math.h>
#include <algorithm>
using namespace std;

#define MAX (1000000)
long long nData[MAX];
long long nKey[MAX];
long long egcd(long long a, long long b, long long& x, long long& y)
{
    if (b == 0)
    {
        x = 1;
        y = 0;
        return a;
    }
    long long ret = egcd(b, a % b, x, y);
    long long t = x;
    x = y;
    y = t - (a / b) * y;
    return ret;
}

long long GetPos(long long key)
{
     return (key ^ 0xA5A5A5A5) % MAX;
}

void Add(long long key, long long data)
{
    long long nPos = GetPos(key);
    while (nData[nPos] != -1)
    {
        nPos = (nPos + 1) % MAX;
    }
    nData[nPos] = data;
    nKey[nPos] = key;
}

int Query(int key)
{
    int nPos = GetPos(key);
    
    while (nData[nPos] != -1)
    {
        if (nKey[nPos] == key)
        {
            return nData[nPos];
        }
        nPos = (nPos + 1) % MAX;
    }
    return -1;
}

long long BabyStep(long long nA, long long nB, long long nP)
{
    long long nM = ceil(sqrt((double)(nP - 1)));
    long long x, y;
    egcd(nP, nA, x, y);//y是nA%p的乘法?/span>
    y = (y + nP) % nP;
    long long nTemp = 1;
    long long c = 1;//c是nA?#8212;m?/span>
    memset(nData, -1, sizeof(nData));
    memset(nKey, -1, sizeof(nKey));
    for (long long j = 0; j < nM; ++j)
    {
        Add(nTemp, j);
        nTemp = (nTemp * nA) % nP;
        c = (c * y) % nP;
    }
    
    long long r = nB;
    for (int i = 0; i < nM; ++i)
    {
        long long j = Query(r);
        if (j != -1)
        {
            return i * nM + j;
        }
        r = (r * c) % nP;
    }
    return -1;
}

int main()
{
    long long nP, nB, nN;
    
    while (scanf("%I64d%I64d%I64d", &nP, &nB, &nN) == 3)
    {
        long long nAns = BabyStep(nB, nN, nP);
        if (nAns == -1)printf("no solution\n");
        else printf("%I64d\n", nAns);
    }
    
    return 0;
}


yx 2012-07-29 19:38 发表评论
]]>
uva 408 - Uniform Generatorhttp://www.shnenglu.com/csu-yx-2013/archive/2012/07/28/185487.htmlyxyxSat, 28 Jul 2012 14:12:00 GMThttp://www.shnenglu.com/csu-yx-2013/archive/2012/07/28/185487.htmlhttp://www.shnenglu.com/csu-yx-2013/comments/185487.htmlhttp://www.shnenglu.com/csu-yx-2013/archive/2012/07/28/185487.html#Feedback0http://www.shnenglu.com/csu-yx-2013/comments/commentRss/185487.htmlhttp://www.shnenglu.com/csu-yx-2013/services/trackbacks/185487.html格都错了Q又忘记打空行,明明字符串从25列开始,中间?个空格的Q我nc的打?个空|pe了,q有不仔l看输出要求Q没有输出空
行,最q真没状态啊?br />   其实Q这个题想通了很单了Q还是数论里面的的概念Q就是加法群的生成群啊,打着随机数的q子而已。由于又没有限定U子Q限?br />对答案也没有影响Q假讄子是0Q那么数列可以表CZؓa*stepQ数列要能够生成0 - mod-1中所有的数字Q那么就有a*step = b % mod
(0<=b<mod)?br />   哈哈Q上面那个式子就是a*x=b%nq个U性同余方E了Q只是有很多b了。要方程有解Q不是需要满x件gcd(a,n)|b么,意思b?br />gcd(a,n)的整数倍了。但?<=b<n啊,b会是1了,那么gcd(a,n)一定是1了哦。那么直接判断gcd(step,mod)是否?p了,哈哈?br />   关于U性同余方Ea*x=b%nQ要有解的条件gcd(a,n)|b的解释,q是参看法D或者其它资料吧。。?br />
代码非常简单了Q如下:
#include <stdio.h>
#include <algorithm>
using namespace std;

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 main()
{
    int nStep, nMod;
    
    while (scanf("%d%d", &nStep, &nMod) == 2)
    {
        printf("%10d%10d    %s\n\n", nStep, nMod,
               gcd(nStep, nMod) == 1 ? "Good Choice" : "Bad Choice");
    }
    
    return 0;
}


yx 2012-07-28 22:12 发表评论
]]>
poj 2115 C Looooopshttp://www.shnenglu.com/csu-yx-2013/archive/2012/07/27/185345.htmlyxyxFri, 27 Jul 2012 09:08:00 GMThttp://www.shnenglu.com/csu-yx-2013/archive/2012/07/27/185345.htmlhttp://www.shnenglu.com/csu-yx-2013/comments/185345.htmlhttp://www.shnenglu.com/csu-yx-2013/archive/2012/07/27/185345.html#Feedback0http://www.shnenglu.com/csu-yx-2013/comments/commentRss/185345.htmlhttp://www.shnenglu.com/csu-yx-2013/services/trackbacks/185345.html法导论。这个方E{换ؓn*c = (b-a) % 2的kơ。根据数论的知识Q? ax = b%nQ需要保证gcd(a,n)|bQ意思b是gcd(a,n)的倍数Q这?br />一下子也很难解释清楚啊Q不满q个条gQ就是没解了。还有,如果有解的话Q解的个数就是d = gcd(a,n)。而且其中一个解是x0 = x'(b
/ d)Q其中x'是用扩展Ƨ几里d法求出来的Q满_pda*x'+n*y'=d?br />   但是q个题不仅仅用到数论的这些知识,因ؓ必须求满x件的最解Q而如果有解的话是d个,而且满解x = x0 + i(b/d)Q?br />Q?<=i<=d)。既然要求最的解,那么对解mod(n/d)卛_了,因ؓ它们之间的差都是n/d的倍数?br />
   代码如下Q?br />
#include <stdio.h>
#include <math.h>
#include <algorithm>
using namespace std;

//扩展Ƨ几里d法
//d = a * x + b * yQd是a和b的最大公U数
long long egcd(long long a, long long b, long long& x, long long& y)
{
    if (b == 0)
    {
        x = 1;
        y = 0;
        return a;
    }
    else
    {
        long long nRet = egcd(b, a % b, x, y);
        long long t = x;
        x = y;
        y = t - (a / b) * y;
        return nRet;
    }
}

int main()
{
    long long nA, nB, nC, nK;

    while (scanf("%I64d%I64d%I64d%I64d", &nA, &nB, &nC, &nK),
            nA || nB || nC || nK)
    {
        long long x, y;
        long long n = pow((double)2, (double)nK) + 1e-8;
        long long d = egcd(n, nC, x, y);
        long long b = (nB - nA + n) % n;
        if (b % d)//如果d | bp|
        {
            printf("FOREVER\n");
        }
        else
        {
            //printf("y:%I64d, b:%I64d, d:%I64d n:%I64d\n", y, b, d, n);
            y = (y + n) % n;
            long long ans = (y * (b / d)) % (n / d);
            printf("%I64d\n", ans);
        }
    }

    return 0;
}


yx 2012-07-27 17:08 发表评论
]]>
poj 2407 Relativeshttp://www.shnenglu.com/csu-yx-2013/archive/2012/07/26/185245.htmlyxyxThu, 26 Jul 2012 13:36:00 GMThttp://www.shnenglu.com/csu-yx-2013/archive/2012/07/26/185245.htmlhttp://www.shnenglu.com/csu-yx-2013/comments/185245.htmlhttp://www.shnenglu.com/csu-yx-2013/archive/2012/07/26/185245.html#Feedback0http://www.shnenglu.com/csu-yx-2013/comments/commentRss/185245.htmlhttp://www.shnenglu.com/csu-yx-2013/services/trackbacks/185245.html那么公式n∏(1-1/p)Q其中p是n的素数因子,可以得到直观的理解了。但是计的时候,会将q个式子变Ş下,得到另外一个Ş式?br />   如图所C:

   但是q个题,需要考虑下,有可能n是个大素敎ͼ直接q行因子分解的话会超时的。怎么办了Q只能在分解的时候判断n是不是已l成?br />素数了,如果是素敎ͼ{案再乘以n-1p了。ؓ了加快判断,我用5mb的空间搞了个素数表,大于5000000的数字只能@环判断了?br />
 代码如下Q注意求Ƨ拉函数的代码部分:
#include <stdio.h>
#include <math.h>
#define MAX (5000000)
bool bPrime[MAX];//false表示素数

void InitPrime()
{
    bPrime[0] = bPrime[1] = true;
    int nMax = sqrt((double)MAX) + 1;
    for (int i = 2; i <= nMax; ++i)
    {
        if (!bPrime[i])
        for (int j = i * 2; j < MAX; j += i)
        {
            bPrime[j] = true;
        }
    }
}

bool IsPrime(int nN)
{
    if (nN < MAX)
    {
        return !bPrime[nN];
    }
    else
    {
        int nMax = sqrt((double)nN) + 1;
        for (int i = 2; i <= nMax; ++i)
        {
            if (nN % i == 0)
            {
                return false;
            }
        }
        return true;
    }
}

int main()
{
    int nN;
    
    InitPrime();
    while (scanf("%d", &nN), nN)
    {
        if (nN == 1){printf("0\n");continue;}
        int nAns = 1;
        for (int i = 2; i <= nN; ++i)
        {
            if (IsPrime(nN))
            {
                nAns *= nN - 1;
                break;
            }
            if (nN % i == 0)
            {
                nAns *= i - 1;
                nN /= i;
                while (nN % i == 0)
                {
                    nAns *= i;
                    nN /= i;
                }
            }
        }
        printf("%d\n", nAns);
    }
    
    return 0;
}



yx 2012-07-26 21:36 发表评论
]]>
poj 2551 Ones and poj 2262 Goldbach's Conjecturehttp://www.shnenglu.com/csu-yx-2013/archive/2012/07/25/185074.htmlyxyxWed, 25 Jul 2012 14:35:00 GMThttp://www.shnenglu.com/csu-yx-2013/archive/2012/07/25/185074.htmlhttp://www.shnenglu.com/csu-yx-2013/comments/185074.htmlhttp://www.shnenglu.com/csu-yx-2013/archive/2012/07/25/185074.html#Feedback0http://www.shnenglu.com/csu-yx-2013/comments/commentRss/185074.htmlhttp://www.shnenglu.com/csu-yx-2013/services/trackbacks/185074.html用一个m乘以n得到的答案全?l成的数字,?最的个数是多。可以{换ؓn*m=(k*10+1)Q那么可以得?k*10+1)%n==0?br />当然最开始的k?Q那么我们不断的增长k = Q?0*k+1Q。看增长多少ơ,是有多个1了。因避免溢出Q所以需要不?n?br />因ؓ同余的性质Q所以可以保?n之后{案不变?br />   W二个用到素数筛选法。素数筛选法的原理是{去素数的倍数Q由于是从小循环到大的,所以当前的值没被筛掉的话,则一定是素数Q?br />q个判断D复杂度不是n的^斏V?br />
   poj 2551 代码Q?br />   
#include <stdio.h>
int main()
{
    int nN;
    
    while (scanf("%d", &nN) == 1)
    {
        int nCnt = 1;
        int nTemp = 1;
        while (1)
        {
            if (nTemp % nN == 0)break;
            else nTemp = (nTemp * 10 + 1) % nN;
            ++nCnt;
        }
        printf("%d\n", nCnt);
    }
    
    return 0;
}
   poj 2262 代码Q?br />
#include <stdio.h>
#include <string.h>
#include <math.h>

#define MAX (1000000 + 10)
bool bPrime[MAX];
void InitPrime()
{
    memset(bPrime, truesizeof(bPrime));
    bPrime[0] = bPrime[1] = false;
    for (int i = 2; i <= MAX; ++i)
    {
        if (bPrime[i])
        for (int j = 2 * i; j <= MAX; j += i)
        {
            bPrime[j] = false;
        }
    }
}

int main()
{
    int nN;
    
    InitPrime();
    while (scanf("%d", &nN), nN)
    {
        int i;
        for (i = 2; i < nN; ++i)
        {
            if (i % 2 && (nN - i) % 2 && bPrime[i] && bPrime[nN - i])
            {
                printf("%d = %d + %d\n", nN, i, nN - i);
                break;
            }
        }
        if (i == nN)
        {
            printf("Goldbach's conjecture is wrong.\n");
        }
    }
    
    return 0;
}


yx 2012-07-25 22:35 发表评论
]]>
þþþþþòҰ¸߳| ¾þþþa| þþþùƷ| ˾Ʒþ޸岻| ˾Ʒþۺ| þþþAVۺϲҰ | 88þþƷһëƬ | ھƷþþþӰԺһ | 99ƷۺϾþþþ | þ˽˹Ʒ| 99reþùƷҳ| vaþþþ| 99þ99þþƷƬ| 㽶aaþëƬ| þۺ| þٸ۲AV| þ99Ʒһ| Ļþһ| þ91ƷۺϹҳ| վþþ| þþƷ99Ʒ| þûƵ| þۺϾɫۺŷݺ| þþƷ| ޹˾þۺ| ŷ þ| 99Ʒþ| һɫþۺ޾Ʒ| ޹þþþþþ| þþƷѴƬƬ| ޹Ʒþ66| 999Ʒþþþþ| þ99Ƶ| þþùƷ| ƷþòҰ| žžþȻ㽶ͼƬ| ɫۺϾþþþר| þþƷɫ鶹| þֻоƷ߹ۿ| yy6080þ| þþƷ99þþ|