- 题目描述 Description
落冰从悬崖上被冲下,虽有落令的精魂保护大难不死,但已消耗了大半法力。此时的棂刚刚也连续经历了三场恶战,身负重伤。夜色中他们急于撤出迷雾丛林,途中却被拉尔法的磁阵困住。这个磁阵专门用来对付落冰,由于洛伦兹力的作用,为避免给自己造成伤害,落冰被迫把自身的电流降到接近0,也因此暂时失去了攻击能力。拉尔法得意地阴笑着,因为他看出了棂的重伤,并认为自己可以轻易战胜棂。
然而,身经百战的棂早已看穿了一切,他知道拉尔法用大脑控制磁阵。棂和拉尔法之间的磁阵可以看作一个a行b列的矩阵。(他们都在矩阵的外面)棂可以在短时间内控制少量的γ光子,这些光子可以从某一列的任何一个格子出发,到达下一列的任何一个格子,(当然光子一开始从棂出发,可到达第1列的任何一个格子;也可以从第b列——即最后一列——的任何一个格子出发到达拉尔法)当光子到达拉尔法所在的位置时,虽然伤害可以忽略不计,但光子可以对拉尔法的大脑造成扰动(大脑的思考是在量子层面的嘛),然后磁阵强度就会有一定程度的削弱。并且光子到达拉尔法的不同路径数越多,对拉尔法造成的扰动就越大,磁阵削弱得也越厉害。
这里一条路径指的是光子从棂出发经过b列之后到达了拉尔法所经过的路径。光子只能从某一列到下一列,不能返回到前面的列,也不能在同一列的两个格子运动。
现在,棂想知道一共有多少种不同的路径,然后他就可以心算出光子对拉尔法造成的扰动和磁阵被削弱的程度,并挑选合适的符咒发动攻击。棂没带笔记本,因此他通过虚数空间把a和b的值告诉了梦中的晓筱。然而晓筱梦见了一个令人费解的数p,经过一番思索,她认为p也是棂告诉的,意思是把答案mod p,因为棂总是很关心她,不想麻烦她写高精。但晓筱参透了p的含义以后,剩余的脑细胞不足以计算出总路径数,于是她请精通OI的你来帮她。
- 输入描述 Input Description
只有一行,有3个整数a,b,p,含义同题目描述。
- 输出描述 Output Description
只有一个整数,为总路径数mod p以后的值。
- 样例输入 Sample Input
样例输入1:
2 10 1000
样例输入2:
3 6 1000
- 样例输出 Sample Output
样例输出1:
24
样例输出2:
729
- 数据范围及提示 Data Size & Hint
对于20%的数据,b≤105;
对于40%的数据,b≤1050;
对于100%的数据,a,p≤10000;b≤101000000;
数据全部随机;
(感觉这样的数据规模并不够大)
- 题解
一件事:找到一条路径;
完成这件事可以分b步,其中每一步都有a种方案;
根据分步乘法计数原理,总方案数=ab,本题就转化成了求abmodp了。
套公式abmodp=a(bmodφ(p))+φ(p)modp,b≥φ(p),大整数的处理方式与fzu1759如出一辙,数据还弱不少,直接拿1759代码改一改就行了。
- Code
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#define ll long long
using namespace std;
char ch[1000010];
inline ll singleEulerPhi(ll a)
{
ll ans = a;
for(ll i = 2; i <= (ll)sqrt(a * 10); ++i) if(a % i == 0)
{
ans = ans / i * (i - 1);
while(a % i == 0) a /= i;
}
if(a > 1) ans = ans / a * (a - 1);
return ans;
}
inline ll quickPow(ll a, ll b, ll m)
{
ll ans = 1;
for(ll t = a; b; b >>= 1, t = (t % m) * (t % m) % m)
if(b & 1) ans = (ans % m) * (t % m) % m;
return ans;
}
inline void write(ll a)
{
int top = 0;
char ch[50];
if(a < 0)
{
putchar(‘-‘);
a = -a;
}
do {
ch[top++] = a%10 + 48;
a /= 10;
} while(a);
while(top--) putchar(ch[top]);
putchar(‘\n‘);
}
int main()
{
ll a, b, c, phi, len;
scanf("%lld", &a); scanf("%s", &ch); scanf("%lld", &c);
len = strlen(ch); phi = singleEulerPhi(c);
b = 0LL;
for(int i = 0; i < len; ++i)
{
b = b * 10 + ch[i] - 48;
b %= phi;
}
write(quickPow(a, b, c));
return 0;
}