专栏文章

题解:P9777 [HUSTFC 2023] Fujisaki 讨厌数学

P9777题解参与者 2已保存评论 1

文章操作

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

当前评论
1 条
当前快照
1 份
快照标识符
@mir4rhxz
此快照首次捕获于
2025/12/04 15:44
3 个月前
此快照最后确认于
2025/12/04 15:44
3 个月前
查看原文

题意

给出 x+1x(k)x+\frac{1}{x}(k)xn+1xnx^n+ \frac{1}{x^n}

思路

首先可以想到递推。
fi=xi+1xif_i=x^i+ \frac{1}{x^i}
考虑转移。
fi=xi+1xi=xi+1xi+xi2+1xi2(xi2+1xi2)=(xi1+1xi1)(x+1x)(xi2+1xi2)=k×fi1fi2\begin{aligned} f_i&=x^i+ \frac{1}{x^i}&\\ &=x^i+ \frac{1}{x^i}+x^{i-2}+\frac{1}{x^{i-2}}-(x^{i-2}+\frac{1}{x^{i-2}})&\\ &=(x^{i-1}+\frac{1}{x^{i-1}})(x+\frac{1}{x})-(x^{i-2}+\frac{1}{x^{i-2}})&\\ &=k\times f_{i-1}-f_{i-2} \end{aligned}
n1018n\le 10^{18},矩阵加速即可。

代码

CPP
#include<bits/stdc++.h>
#define int long long
using namespace std;
int m,k,n;

struct mat{
	int a[3][3];
	void build(){
		for(int i=1;i<=2;++i)
			for(int j=1;j<=2;++j)
				a[i][j]=0;
	}
	mat operator*(const mat x)const{
		mat res;
		res.build();
		for(int i=1;i<=2;++i){
			for(int j=1;j<=2;++j){
				for(int p=1;p<=2;++p){
					res.a[i][j]+=a[i][p]*x.a[p][j]%m;
					res.a[i][j]%=m;
				}
			} 
		} 
		return res;
	}
};

signed main(){
	cin>>m>>k>>n;
	if(n==1){
		cout<<k;
		return 0;
	}
	if(n==0){
		cout<<2;
		return 0;
	}
	mat x;
	x.a[1][1]=0,x.a[1][2]=-1;
	x.a[2][1]=1,x.a[2][2]=k;
	mat res;
	res.build();
	res.a[1][1]=res.a[2][2]=1;
	--n;
	while(n){
		if(n&1)
			res=res*x;
		x=x*x;
		n>>=1;
	}
	cout<<((2*res.a[1][2]+k*res.a[2][2])%m+m)%m;
}

评论

1 条评论,欢迎与作者交流。

正在加载评论...