CodeForces 17D Notepad (欧拉降幂)

Description:

Nick is attracted by everything unconventional. He doesn’t like decimal number system any more, and he decided to study other number systems. A number system with base b caught his attention. Before he starts studying it, he wants to write in his notepad all the numbers of length n without leading zeros in this number system. Each page in Nick’s notepad has enough space for c numbers exactly. Nick writes every suitable number only once, starting with the first clean page and leaving no clean spaces. Nick never writes number 0 as he has unpleasant memories about zero divide.

Would you help Nick find out how many numbers will be written on the last page.

Input

The only input line contains three space-separated integers b , n b, n and c c ( 2 b < 1 0 1 0 6 , 1 n < 1 0 1 0 6 , 1 c 1 0 9 2 ≤ b < 10^{10^6}, 1 ≤ n < 10^{10^6}, 1 ≤ c ≤ 10^9 ). You may consider that Nick has infinite patience, endless amount of paper and representations of digits as characters. The numbers doesn’t contain leading zeros.

Output

In the only line output the amount of numbers written on the same page as the last number.

Examples

Input

2 3 3

Output

1

Input

2 3 4

Output

4
Note
In both samples there are exactly 4 4 numbers of length 3 3 in binary number system. In the first sample Nick writes 3 3 numbers on the first page and 1 1 on the second page. In the second sample all the 4 4 numbers can be written on the first page.

题意:

有个本子,往本子上写全部长度为 n n b b 进制数,每页可以写 c c 个。
要求数字要求所有数字必须严格不含前导 0 0 。求最后一页上有多少个数字。
考虑第一位不能为 0 0 ,只能有 b 1 ( [ 1 , b 1 ] ) b−1([1,b−1]) 种填法
考虑后 n 1 n−1 位可以填 [ 0 , b 1 ] [0,b−1] ,则有 b n 1 b^{n−1} 种填法
显然 a n s = ( b 1 ) × b n 1 m o d c ans=(b−1)×b^{n−1}modc
若ans=0 ,则答案为p,因为不用翻开下一页。
规律好找,
因为给出的数据是很大的所以直接快速幂是会 w a 18 wa18 的,所以要用到欧拉降幂。

AC代码:

#include <cstdio>
#include <vector>
#include <queue>
#include <cstring>
#include <cmath>
#include <map>
#include <set>
#include <string>
#include <iostream>
#include <algorithm>
#include <iomanip>
#include <stack>
#include <queue>
using namespace std;
#define sd(n) scanf("%d", &n)
#define sdd(n, m) scanf("%d%d", &n, &m)
#define sddd(n, m, k) scanf("%d%d%d", &n, &m, &k)
#define pd(n) printf("%d\n", (n))
#define pdd(n, m) printf("%d %d\n", n, m)
#define pld(n) printf("%lld\n", n)
#define pldd(n, m) printf("%lld %lld\n", n, m)
#define sld(n) scanf("%lld", &n)
#define sldd(n, m) scanf("%lld%lld", &n, &m)
#define slddd(n, m, k) scanf("%lld%lld%lld", &n, &m, &k)
#define sf(n) scanf("%lf", &n)
#define sff(n, m) scanf("%lf%lf", &n, &m)
#define sfff(n, m, k) scanf("%lf%lf%lf", &n, &m, &k)
#define rep(i, a, n) for (int i = a; i <= n; i++)
#define per(i, n, a) for (int i = n; i >= a; i--)
#define mem(a, n) memset(a, n, sizeof(a))
#define debug(x) cout << #x << ": " << x << endl
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define fi first
#define se second
#define mod(x) ((x) % MOD)
#define gcd(a, b) __gcd(a, b)
#define lowbit(x) (x & -x)
typedef pair<int, int> PII;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
const int MOD = 1e9 + 7;
const double eps = 1e-9;
const ll INF = 0x3f3f3f3f3f3f3f3fll;
const int inf = 0x3f3f3f3f;
inline int read()
{
    int ret = 0, sgn = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9')
    {
        if (ch == '-')
            sgn = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9')
    {
        ret = ret * 10 + ch - '0';
        ch = getchar();
    }
    return ret * sgn;
}
inline void Out(int a) //Êä³öÍâ¹Ò
{
    if (a > 9)
        Out(a / 10);
    putchar(a % 10 + '0');
}

ll gcd(ll a, ll b)
{
    return b == 0 ? a : gcd(b, a % b);
}

ll lcm(ll a, ll b)
{
    return a * b / gcd(a, b);
}
///快速幂m^k%mod
ll qpow(ll a, ll b, ll mod)
{
    if (a >= mod)
        a = a % mod + mod;
    ll ans = 1;
    while (b)
    {
        if (b & 1)
        {
            ans = ans * a;
            if (ans >= mod)
                ans = ans % mod + mod;
        }
        a *= a;
        if (a >= mod)
            a = a % mod + mod;
        b >>= 1;
    }
    return ans;
}

// 快速幂求逆元
int Fermat(int a, int p) //费马求a关于b的逆元
{
    return qpow(a, p - 2, p);
}

///扩展欧几里得
ll exgcd(ll a, ll b, ll &x, ll &y)
{
    if (b == 0)
    {
        x = 1, y = 0;
        return a;
    }
    ll d = exgcd(b, a % b, x, y);
    ll z = x;
    x = y;
    y = z - y * (a / b);
    return d;
}

///中国剩余定理模板0
ll china(int a[], int b[], int n) //a[]为除数,b[]为余数
{
    ll M = 1, y, x = 0;
    for (int i = 0; i < n; ++i) //算出它们累乘的结果
        M *= a[i];
    for (int i = 0; i < n; ++i)
    {
        int w = M / a[i];
        ll tx = 0;
        ll t = exgcd(w, a[i], tx, y); //计算逆元
        x = (x + w * (b[i] / t) * x) % M;
    }
    return (x + M) % M;
}

const int maxn = 3e6 + 10;
char b[maxn], s[maxn];
ll c;
ll mult(ll a, ll b) ///a^b%c
{
    ll z = 1;
    while (b)
    {
        if (b & 1)
            z = (z * a) % c;
        a = (a * a) % c;
        b /= 2;
    }
    return z;
}
ll phi(ll n) ///欧拉函数
{
    ll rea = n;
    for (int i = 2; i * i <= n; i++)
        if (n % i == 0)
        {
            rea = rea - rea / i;
            do
                n /= i;
            while (n % i == 0);
        }
    if (n > 1)
        rea = rea - rea / n;
    return rea;
}
int main()
{
    ll bb, n, len1, len2;
    scanf("%s%s%lld", b, s, &c);
    bb = 0;
    n = 0;
    len1 = strlen(b);
    len2 = strlen(s);
    int cnt = phi(c);
    rep(i, 0, len1 - 1)
    {
        bb = (bb * 10 + b[i] - '0') % c;
    }
    bool ok = 0;
    rep(i, 0, len2 - 1)
    {
        n = n * 10 + s[i] - '0';
        if (n > cnt)
        {
            ok = 1;
            n = n % cnt;
        }
    }
    if (ok)
        n += cnt;
    n--;
    ll ans = 0;
    if (bb == 0)
        bb = c;
    ans = mult(bb, n);
    ans = (((bb + c - 1) % c) * ans) % c;
    if (ans != 0)
        pld(ans);
    else
        pld(c);
    return 0;
}

发布了631 篇原创文章 · 获赞 399 · 访问量 20万+

猜你喜欢

转载自blog.csdn.net/qq_43627087/article/details/104171243
今日推荐