洛谷1050 循环

原题链接

觉得这个大佬写的挺好的就直接复制过来了(略有改动)。

我们可以从尾来分析,即后\(1\)位,后\(2\)位,后\(3\)位,后\(4\)位……后\(k\)位,递推去找。
假使输入数据位\(198123\ 4\)
1.截取后\(4\)\(8123\),只需对\(8123\)做处理。
2.首先取最后一位\(3\),寻找循环节:\(3,9,7,1\),循环长度为\(4\)
3.此时,取后两位\(23\),而\((23 ^ 4) \mod 100 = 41\),此时,\(23\)需每次乘以\(41\),可保证最后一位不变。\(23 \times 41 ^ n\)的循环节为\(43\ 63\ 83\ 3\ 23\),循环节长度为\(5\),此时,循环总长度为\(4 \times 5 = 20\)
4.通过第\(3\)步操作,取后三位\(123\)\((123 ^ {20}) \mod 1000 = 201\)\(123 \times 201 ^ n\)的循环节为\(723\ 323\ 923\ 523\ 123\),循环节长度为\(5\),此时总长度为\(20 \times 5 = 100\)
5.还是一样,取后四位\(8123\)\((8123 ^ {100}) \mod 10000 = 6001\)\(8123 \times 6001 ^ n\)的循环节为\(6123\ 4123\ 2123\ 123\ 8123\),循环节长度为\(5\),此时总长度为\(100 \times 5 = 500\)

上高精按上述放方法模拟即可。
因为我比较懒,就直接复制了我的高精模板。

#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
const int base = 1e8;
const int N = 1e3 + 10;
int aux[N << 3];
struct bigint {
    int s[N], l;
    void CL() { l = 0; memset(s, 0, sizeof(s)); }
    void pr()
    {
        printf("%d", s[l]);
        for (int i = l - 1; i; i--)
            printf("%08d", s[i]);
    }
    void re_l()
    {
        int i, x = 0, k = 1, L = 0, fl, o;
        char c = getchar();
        for (; c < '0' || c > '9'; c = getchar());
        for (; c >= '0' && c <= '9'; c = getchar())
        {
            if (!(L - 1) && !aux[L])
                L--;
            aux[++L] = c - '0';
        }
        CL();
        l = L / 8 + ((o = L % 8) > 0);
        for (i = 1; i <= o; i++)
            x = x * 10 + aux[i];
        if (o)
            s[l] = x;
        fl = !o ? l + 1 : l;
        for (i = o + 1, x = 0; i <= L; i++, k++)
        {
            x = x * 10 + aux[i];
            if (!(k ^ 8))
            {
                s[--fl] = x;
                x = k = 0;
            }
        }
        if (!l)
            l = 1;
    }
    ll toint()
    {
        ll x = 0;
        for (int i = l; i; i--)
            x = x * base + s[i];
        return x;
    }
    bigint operator = (int b)
    {
        CL();
        do
        {
            s[++l] = b % base;
            b /= base;
        } while (b > 0);
        return *this;
    }
    bigint operator = (ll b)
    {
        CL();
        do
        {
            s[++l] = b % base;
            b /= base;
        } while (b > 0);
        return *this;
    }
    bigint operator + (const int &b)
    {
        bigint c = *this;
        ll x = b;
        for (int i = 1; i <= l && x; i++)
        {
            x = x + c.s[i];
            c.s[i] = x % base;
            x /= base;
        }
        if (x)
            c.s[++c.l] = x;
        return c;
    }
    bigint operator + (const ll &b)
    {
        bigint c = *this;
        ll x = b;
        for (int i = 1; i <= l && x; i++)
        {
            x = x + c.s[i];
            c.s[i] = x % base;
            x /= base;
        }
        if (x)
            c.s[++c.l] = x;
        return c;
    }
    bigint operator + (bigint &b)
    {
        if (b.l < 3)
            return *this + b.toint();
        bigint c;
        ll x = 0;
        int k = l < b.l ? b.l : l;
        c.CL();
        c.l = k;
        for (int i = 1; i <= k; i++)
        {
            x = x + s[i] + b.s[i];
            c.s[i] = x % base;
            x /= base;
        }
        if (x)
            c.s[++c.l] = x;
        return c;
    }
    bigint operator - (const bigint &b)
    {
        bigint c, d = *this;
        ll x = 0;
        c.CL();
        for (int i = 1; i <= l; i++)
        {
            if ((x = d.s[i]) < b.s[i])
            {
                d.s[i + 1]--;
                x += base;
            }
            c.s[i] = x - b.s[i];
        }
        c.l = l;
        for (; !c.s[c.l] && c.l > 1; c.l--);
        return c;
    }
    bigint operator - (const int &b)
    {
        bigint c;
        return *this - (c = b);
    }
    bigint operator - (const ll &b)
    {
        bigint c;
        return *this - (c = b);
    }
    bigint operator * (const int &b)
    {
        bigint c;
        ll x = 0;
        c.CL();
        for (int i = 1; i <= l; i++)
        {
            x = x + 1LL * s[i] * b;
            c.s[i] = x % base;
            x /= base;
        }
        for (c.l = l; x; x /= base)
            c.s[++c.l] = x % base;
        return c;
    }
    bigint operator * (bigint &b)
    {
        if (b.l < 2)
            return *this * b.toint();
        bigint c;
        ll x;
        int i, j, k;
        c.CL();
        for (i = 1; i <= l; i++)
        {
            x = 0;
            for (j = 1; j <= b.l; j++)
            {
                x = x + 1LL * s[i] * b.s[j] + c.s[k = i + j - 1];
                c.s[k] = x % base;
                x /= base;
            }
            if (x)
                c.s[i + b.l] = x;
        }
        for (c.l = l + b.l; !c.s[c.l] && c.l > 1; c.l--);
        return c;
    }
    bigint operator * (const ll &b)
    {
        bigint c;
        if (b > 2e9)
        {
            c = b;
            return *this * c;
        }
        ll x = 0;
        c.CL();
        for (int i = 1; i <= l; i++)
        {
            x = x + b * s[i];
            c.s[i] = x % base;
            x /= base;
        }
        for (c.l = l; x; x /= base)
            c.s[++c.l] = x % base;
        return c;
    }
    bigint operator / (const int &b)
    {
        bigint c;
        ll x = 0;
        c.CL();
        for (int i = l; i; i--)
        {
            c.s[i] = (x * base + s[i]) / b;
            x = (x * base + s[i]) % b;
        }
        for (c.l = l; !c.s[c.l] && c.l > 1; c.l--);
        return c;
    }
    bigint operator / (const ll &b)
    {
        bigint c;
        ll x = 0;
        c.CL();
        for (int i = l; i; i--)
        {
            c.s[i] = (x * base + s[i]) / b;
            x = (x * base + s[i]) % b;
        }
        for (c.l = l; !c.s[c.l] && c.l > 1; c.l--);
        return c;
    }
    bigint operator / (bigint &b)
    {
        if (b.l < 2)
            return *this / b.toint();
        bigint c, d;
        int i, j, le, r, mid, k;
        c.CL();
        d.CL();
        for (i = l; i; i--)
        {
            for (j = ++d.l; j > 1; j--)
                d.s[j] = d.s[j - 1];
            d.s[1] = s[i];
            if (d < b)
                continue;
            le = k = 0;
            r = base - 1;
            while (le <= r)
            {
                mid = (le + r) >> 1;
                if (b * mid <= d)
                {
                    le = mid + 1;
                    k = mid;
                }
                else
                    r = mid - 1;
            }
            c.s[i] = k;
            d = d - b * k;
        }
        for (c.l = l; !c.s[c.l] && c.l > 1; c.l--);
        return c;
    }
    bigint operator % (const int &b)
    {
        bigint c;
        ll x = 0;
        c.CL();
        for (int i = l; i; i--)
            x = (x * base + s[i]) % b;
        return c = x;
    }
    bigint operator % (const ll &b)
    {
        bigint c;
        ll x = 0;
        c.CL();
        for (int i = l; i; i--)
            x = (x * base + s[i]) % b;
        return c = x;
    }
    bigint operator % (bigint &b)
    {
        if (b.l < 2)
            return *this % b.toint();
        bigint c;
        int i, j, le, r, mid, k;
        c.CL();
        for (i = l; i; i--)
        {
            for (j = ++c.l; j > 1; j--)
                c.s[j] = c.s[j - 1];
            c.s[1] = s[i];
            if (c < b)
                continue;
            le = k = 0;
            r = base - 1;
            while (le <= r)
            {
                mid = (le + r) >> 1;
                if (b * mid <= c)
                {
                    le = mid + 1;
                    k = mid;
                }
                else
                    r = mid - 1;
            }
            c = c - b * k;
        }
        for (; !c.s[c.l] && c.l > 1; c.l--);
        return c;
    }
    bigint operator += (bigint &b)
    {
        return *this = *this + b;
    }
    bigint operator += (ll &b)
    {
        return *this = *this + b;
    }
    bigint operator += (int &b)
    {
        return *this = *this + b;
    }
    bigint operator -= (bigint &b)
    {
        return *this = *this - b;
    }
    bigint operator -= (ll &b)
    {
        return *this = *this - b;
    }
    bigint operator -= (int &b)
    {
        return *this = *this - b;
    }
    bigint operator *= (bigint &b)
    {
        return *this = *this * b;
    }
    bigint operator *= (ll &b)
    {
        return *this = *this * b;
    }
    bigint operator *= (int &b)
    {
        return *this = *this * b;
    }
    bigint operator /= (bigint &b)
    {
        return *this = *this / b;
    }
    bigint operator /= (ll &b)
    {
        return *this = *this / b;
    }
    bigint operator /= (int &b)
    {
        return *this = *this / b;
    }
    bigint operator %= (bigint &b)
    {
        return *this = *this % b;
    }
    bigint operator %= (ll &b)
    {
        return *this = *this % b;
    }
    bigint operator %= (int &b)
    {
        return *this = *this % b;
    }
    bool operator < (const bigint &b) const
    {
        if (l ^ b.l)
            return l < b.l;
        for (int i = l; i; i--)
            if (s[i] ^ b.s[i])
                return s[i] < b.s[i];
        return false;
    }
    bool operator <= (const bigint &b) const
    {
        if (l ^ b.l)
            return l < b.l;
        for (int i = l; i; i--)
            if (s[i] ^ b.s[i])
                return s[i] < b.s[i];
        return true;
    }
    bool operator > (const bigint &b) const
    {
        if (l ^ b.l)
            return l > b.l;
        for (int i = l; i; i--)
            if (s[i] ^ b.s[i])
                return s[i] > b.s[i];
        return false;
    }
    bool operator >= (const bigint &b) const
    {
        if (l ^ b.l)
            return l > b.l;
        for (int i = l; i; i--)
            if (s[i] ^ b.s[i])
                return s[i] > b.s[i];
        return true;
    }
    bool operator == (const bigint &b) const
    {
        if (l ^ b.l)
            return false;
        for (int i = l; i; i--)
            if (s[i] ^ b.s[i])
                return false;
        return true;
    }
    bool operator != (const bigint &b) const
    {
        if (l ^ b.l)
            return true;
        for (int i = l; i; i--)
            if (s[i] ^ b.s[i])
                return true;
        return false;
    }
    bool operator < (ll b) const
    {
        bigint c;
        return *this < (c = b);
    }
    bool operator <= (ll b) const
    {
        bigint c;
        return *this <= (c = b);
    }
    bool operator > (ll b) const
    {
        bigint c;
        return *this > (c = b);
    }
    bool operator >= (ll b) const
    {
        bigint c;
        return *this >= (c = b);
    }
    bool operator == (ll b) const
    {
        bigint c;
        return *this == (c = b);
    }
    bool operator != (ll b) const
    {
        bigint c;
        return *this != (c = b);
    }
    bool operator < (int b) const
    {
        bigint c;
        return *this < (c = b);
    }
    bool operator <= (int b) const
    {
        bigint c;
        return *this <= (c = b);
    }
    bool operator > (int b) const
    {
        bigint c;
        return *this > (c = b);
    }
    bool operator >= (int b) const
    {
        bigint c;
        return *this >= (c = b);
    }
    bool operator == (int b) const
    {
        bigint c;
        return *this == (c = b);
    }
    bool operator != (int b) const
    {
        bigint c;
        return *this != (c = b);
    }
};
bigint n, an, mod[N], la, nw, m;
bigint ksm(bigint x, bigint y, bigint md)
{
    bigint s;
    s = 1;
    for (; y > 0; y = y / 2, x = x * x % md)
        if (y.s[1] & 1)
            s = s * x % md;
    return s;
}
int main()
{
    int i, j, k;
    n.re_l(); scanf("%d", &k);
    for (mod[1] = 10, i = 2; i <= k; i++)
        mod[i] = mod[i - 1] * 10;
    n %= mod[k];
    for (an = 1, i = 1; i <= k; i++)
    {
        nw = n % mod[i];
        m = ksm(nw, an, mod[i]);
        i ^ 1 ? la = nw = nw * m % mod[i] : la = nw;
        for (j = 2; j < 12; j++)
        {
            nw = nw * m % mod[i];
            if (nw == la)
                break;
        }
        if (j > 11)
        {
            printf("-1");
            return 0;
        }
        an = an * (j - 1);
    }
    an.pr();
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/Iowa-Battleship/p/10223613.html