acdream 1124 喵喵的遗憾 fib循环节

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;


#define LL long long

const int M = 2;
struct mat {
	LL a[M][M];
};
mat A, I = {1, 0, 0, 1};
mat multi(mat a, mat b, LL mod) {
	mat ret;
	for(int i = 0; i < M; ++i)
		for(int j = 0; j < M; ++j) {
			ret.a[i][j] = 0;
			for(int k = 0; k < M; ++k)
				ret.a[i][j] = (ret.a[i][j] + a.a[i][k] * b.a[k][j] % mod) % mod;
		}
	return ret;
}
mat qpow(mat a, LL k, LL mod) {
	mat ret = I;
	while(k) {
		if(k & 1) ret = multi(ret, a, mod);
		k >>= 1, a = multi(a, a, mod);
	}
	return ret;
}
LL gcd(LL a, LL b) {
	if(b == 0) return a;
	return gcd(b, a % b);
}
const int N = 400040;
const int NN = 5005;

LL num[NN], pri[NN], fac[NN];
int cnt, c;
bool prime[N];
int p[N], k;
void isprime() {
	k = 0;
	memset(prime, 1, sizeof(prime));
	for(int i = 2; i < N; ++i) {
		if(prime[i]) {
			p[k++] = i;
			for(int j = i + i; j < N; j += i)
				prime[j] = 0;
		}
	}
}
LL qpow(LL a, LL k, LL mod) {
	LL ret = 1;
	a %= mod;
	while(k) {
		if(k & 1) ret = ret * a % mod;
		a = a * a % mod, k >>= 1;
	}
	return ret;
}
LL legendre(LL a, LL p) {
	if(qpow(a, (p - 1) >> 1, p) == 1) return 1;
	return -1;
}
void solve(LL n, LL pri[], LL num[]) {
	cnt = 0;
	LL t = (LL)sqrt(1.0 * n);
	for(int i = 0; p[i] <= t; ++i) {
		if(n % p[i] == 0) {
			int a = 0;
			pri[cnt] = p[i];
			while(n % p[i] == 0)
				++ a, n /= p[i];
			num[cnt++] = a;
		}
	}
	if(n > 1) {
		pri[cnt] = n, num[cnt] = 1;
		++cnt;
	}
}
void work(LL n) {
	c = 0;
	LL t = (LL) sqrt(1.0 * n);
	for(int i = 1; i <= t; ++i) {
		if(n % i == 0) {
			if(i * i == n) fac[c++] = i;
			else
				fac[c++] = i, fac[c++] = n / i;
		}
	}
}
LL find_loop(LL n) {
	solve(n, pri, num);
	LL ans = 1;
	for(int i = 0; i < cnt; ++i) {
		LL record = 1;
		if(pri[i] == 2) record = 3;
		else if(pri[i] == 3) record = 8;
		else if(pri[i] == 5) record = 20;
		else {
			if(legendre(5, pri[i]) == 1)
				work(pri[i] - 1);
			else work(2 * (pri[i] + 1));
			sort(fac, fac + c);
			for(int k = 0; k < c; ++k) {
				mat a = qpow(A, fac[k] - 1, pri[i]);
				LL x = (a.a[0][0] + a.a[0][1]) % pri[i];
				LL y = (a.a[1][0] + a.a[1][1]) % pri[i];
				if(x == 1 && y == 0) {
					record = fac[k];
					break;
				}
			}
		}
		for(int k = 1; k < num[i]; ++k) record *= pri[i];
		ans = ans / gcd(ans, record) * record;
	}
	return ans;
}
void init() {
	A.a[0][0] = A.a[0][1] = A.a[1][0] = 1;
	A.a[1][1] = 0;
}

LL f(LL n, LL mod) {
	if(n == 0 || n == 1) return 1;
	mat t = qpow(A, n - 1, mod);
	return (t.a[0][0] + t.a[0][1]) % mod;
}
int readint() {
	char c;
	while((c = getchar()) && !(c >= '0' && c <= '9'));
	int ret = c - '0';
	while((c = getchar()) && c >= '0' && c <= '9')
		ret = (ret << 3) + (ret << 1) + c - '0';
	return ret;
}
int main() {
	init();
	isprime();
	int cas;
	scanf("%d", &cas);
	while(cas--) {
		int n, mod;
		n = readint();
		mod = readint();
		if(mod == 1) {
			puts("0");
			continue;
		}
		LL k1 = find_loop(mod);
		LL k2 = find_loop(k1);
		printf("%lld\n", f(f(f(n, k2), k1), mod));
	}
	return 0;
}

Github下载地址:https://github.com/XLAccount/MiaoBo 项目详解地址:http://www.code4app.com/blog-843201-350.html 快速集成RTMP的视频推流教程:http://www.code4app.com/blog-843201-315.html ffmpeg常用命令操作:http://www.code4app.com/blog-843201-326.html #关于IJKMediaFramework/IJKMediaFramework.h找不到的问题,下载后直接拉到项目中即可 下载地址:https://pan.baidu.com/s/1boPOomN 密码::9yd8 #BUG修复: 解决登录程序偶尔崩溃,修复轮播图片和页面控制器叠加等问题,修复新浪授权登录 (2016.9.7) 解决程序运行中偶尔崩溃问题,解决连续下拉刷新崩溃问题,优化代码 (2016.9.8) 优化直播页面,减少不必要的性能消耗,增加用户体验 (2016.9.11) 适配5s以上的机型除了6sPlus和6Plus延迟较大外,其余延迟都较小,网速好的话可以忽略不计 (2016.9.12) 新版本极大优化程序性能,修复关注数据异常等小问题,重新布局热门页面,减少因反复加载带来的性能消耗 (2016.9.13) 增加个人中心页面,采用下拉放大图片 ➕ 波纹效果 (2016.9.14) ![image text](https://github.com/XLAccount/ALLGIFS/blob/master/psb.gif) 展示图片 ![image](https://github.com/XLAccount/ALLGIFS/blob/master/psb-1.gif) 展示图片 ![image text](https://github.com/XLAccount/ALLGIFS/blob/master/psb-2.gif) 展示图片 ![image text](https://github.com/XLAccount/ALLGIFS/blob/master/psb-3.gif) 展示图片 感谢大神Monkey_ALin http://www.jianshu.com/users/9723687edfb5/latest_articles 的demo支持
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值