题目链接:
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2629
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
int n;
unsigned long long a, b;
// 计算p[i]为模i的周期
int p[1010];
// 计算f[i][j]为f(j) % i
int f[1010][1010*6];
// 计算f(x) % n 的前n^2+1项
//int f[1000010];
//int f[1010][1010];
// p[x][y] = i代表f(i)%n=x, f(i+1)%n=y
//int p[1010][1010];
// 循环的周期
int period;
long long get_result(unsigned long long x, unsigned long long y);
int main()
{
p[1] = 1;
for(int i = 2; i <= 1000; i++)
{
f[i][0] = 0, f[i][1] = 1;
for(int j = 2; ; j++)
{
f[i][j] = (f[i][j-1] + f[i][j-2]) % i;
if(f[i][j] == 1 && f[i][j-1] == 0)
{
p[i] = j-1;
break;
}
}
}
int t;
scanf("%d", &t);
int count = 0;
while(count < t)
{
// scanf("%lld %lld %d", &a, &b, &n);
cin >> a >> b>> n;
/*
memset(p, -1, sizeof(p));
// 计算f(x) % n 的前n^2+1项
int end = n*n+1;
f[0] = 0;
f[1] = 1 % n;
p[f[0]][f[1]] = 0;
// 计算循环的周期
period = -1;
for(int i = 2; i <= end; i++)
{
f[i] = (f[i-1]+f[i-2]) % n;
// printf("f[%d]: %d\n", i, f[i]);
if(p[f[i-1]][f[i]] != -1 && period == -1)
{
period = i-1 - (p[f[i-1]][f[i]]);
// printf("f[%d-1]: %d, f[%d]: %d\n", i, f[i-1], i, f[i]);
}
p[f[i-1]][f[i]] = i-1;
}
// int y = get_result(1, 0);
*/
if(a == 0 || n == 1)
printf("0\n");
else
{
int x = get_result(a % p[n], b);
// 计算f[a^b % period]
printf("%d\n", f[n][x]);
}
count++;
}
return 0;
}
// 计算x ^ y % period
long long get_result(unsigned long long x, unsigned long long y)
{
// printf("x: %lld, y: %lld\n", x, y);
if(y == 0)
{
// printf("here, period\n");
// printf("%d\n", 1 % period);
return 1 % p[n];
}
if(y % 2 == 0)
{
int r1 = get_result(x, y/2);
return (long long)(r1*r1) % p[n];
}
else
{
int r1 = get_result(x, y/2);
return (long long)(r1*r1*x) % p[n];
}
}
主要障碍在计算f(a^b). 因为模n,结果最多n个数,前后两个数情况最多n^2. 所以必定存在循环。计算前n^2个数对,找到循环。
注意点:
1. 64位正整数,只能用unsigned long long 而不是long long. 只能用cin,而不是scanf.
2. 能打表先打表算好
没搞清的疑问(参考代码:https://github.com/aoapc-book/aoapc-bac2nd/blob/master/ch10/UVa11582.cpp):
1. 明明是最多前n^2个数,为何f第二维可以只开到6n?
2. 为何循环必定是和f(0),f(1)相同?