C
题意:
T
T
T组数据,
f
[
0
]
=
0
,
f
[
1
]
=
1
,
f[0]=0,f[1]=1,
f[0]=0,f[1]=1,每次给定
a
,
b
a,b
a,b,问
f
[
a
b
]
m
o
d
n
f[a^b]\mod n
f[ab]modn的值。
数据范围:
1
≤
T
≤
10000
,
0
≤
a
,
b
<
2
64
,
1
≤
n
≤
1000
1\leq T\leq 10000, 0\leq a,b<2^{64},1\leq n\leq 1000
1≤T≤10000,0≤a,b<264,1≤n≤1000
题解:
考虑对
n
n
n取模,则
f
f
f最多有
n
n
n种取值,且最多有
n
2
n^2
n2种组合后,就会出现重复的组合,那么此后的
f
i
f_i
fi将会相同,形成一个循环。因此我们只需要去枚举第一次出现循环的位置即可,即第一次出现
f
[
i
]
=
f
[
1
]
,
f
[
i
−
1
]
=
f
[
0
]
,
i
≥
1
f[i]=f[1],f[i-1]=f[0],i\geq 1
f[i]=f[1],f[i−1]=f[0],i≥1后,
i
−
1
i-1
i−1即一个周期的长度。
f
[
a
b
m
o
d
i
]
m
o
d
n
f[a^b\mod i]\mod n
f[abmodi]modn即为所求。注意特判
0
0
0的情况。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ll;
const int N = 1000010;
int f[N];
ll a, b;
int n, m;
int qp(ll a, ll b, ll mod) {
ll ans = 1 % mod;
while(b) {
if(b & 1) ans = ans * a % mod;
a = a * a % mod;
b >>= 1;
}
return ans;
}
void solve() {
scanf("%llu%llu%d", &a, &b, &n);
if(a == 0 || n == 1) {
puts("0");
return ;
}
f[0] = 0, f[1] = 1 % n;
int len = 0, m = n * n + 1;
for(int i = 2; i <= m; ++i) {
f[i] = (f[i - 1] + f[i - 2]) % n;
if(f[i] == f[1] && f[i - 1] == f[0]) {
len = i - 1;
break;
}
}
if(len == 0) printf("%d\n", f[0]);
else printf("%d\n", f[qp(a % len, b, len)]);
}
int main()
{
int T;
scanf("%d", &T);
for(int i = 1; i <= T; ++i) solve();
return 0;
}