社区讨论

矩阵快速幂求调,回皆关

题目总版参与者 3已保存回复 4

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
3 条
当前快照
1 份
快照标识符
@lszqfxon
此快照首次捕获于
2024/02/24 15:01
2 年前
此快照最后确认于
2024/02/24 17:22
2 年前
查看原帖
好像是输出 00 了,不知道为啥.
CPP
#include <bits/stdc++.h>
#define int long long
using namespace std;
int n, p;

inline int qm(int x) { //光速取模
	if (x < 0) x += p;
	return (x > p ? x - p : x);
}

inline int mul(int a, int b) { //光速乘
	return qm(a * b - (long long)((long double)a * b / p) * p);
}

//inline int mul(int a, int b) { //龟速乘
//	int res = 0;
//	while (b) {
//		if (b & 1) res = qm(res + a);
//		a = qm(a + a);
//		b >>= 1;
//	}
//	return res;
//}

struct node {
	int t[3][3];
	node () {
		memset(t, 0, sizeof t);
	}
	node operator *(const node &x)const { //循环展开
		node res;
		res.t[1][1] = qm(mul(t[1][1], x.t[1][1]) + mul(t[1][2], x.t[2][1]));
		res.t[1][2] = qm(mul(t[1][1], x.t[1][2]) + mul(t[1][2], x.t[2][2]));
		res.t[2][1] = qm(mul(t[2][1], x.t[1][1]) + mul(t[2][2], x.t[2][1]));
		res.t[2][2] = qm(mul(t[2][1], x.t[1][2]) + mul(t[2][2], x.t[2][2]));
		return res;
	}
};

inline node ksmi(node a, int b) { //矩阵快速幂
	node res;
	res.t[1][1] = res.t[2][2] = 1;
	while (b) {
		if (b & 1) res = res * a;
		a = a * a;
		b >>= 1;
	}
	return res;
}

inline int ksmi(int a, int b) { //普通快速幂
	int res = 1;
	while (b) {
		if (b & 1) res = mul(res, a);
		a = mul(a, a);
		b >>= 1;
	}
	return res;
}

signed main() {
	scanf("%lld%lld", &n, &p);
	if (n == 1) {
		printf("0");
		return 0;
	}
	node A0, A;
	A0.t[1][1] = A0.t[2][1] = 1;
	A.t[1][2] = A.t[2][1] = A.t[2][2] = 1;
	A = ksmi(A, n + 2);
	A0 = A * A0;
	int ans = ksmi(A0.t[1][1] - n - 2, n + 1);
	printf("%lld", ans);
	return 0;
}

感觉是光速乘出锅了,因为是第一次用。但是如果换成下面被我注释的龟速乘会 T 掉 4,5,7,8,104,5,7,8,1055 个点。

回复

4 条回复,欢迎继续交流。

正在加载回复...