hdu 4990 Reading comprehension(矩阵乘法)

Read the program below carefully then answer the question.

pragma comment(linker, "/STACK:1024000000,1024000000")

include

include

include

include

include

include

const int MAX=100000*2;
const int INF=1e9;

int main()
{
int n,m,ans,i;
while(scanf("%d%d",&n,&m)!=EOF)
{
ans=0;
for(i=1;i<=n;i++)
{
if(i&1)ans=(ans2+1)%m;
else ans=ans
2%m;
}
printf("%d\n",ans);
}
return 0;
}

可以按照奇偶分类,找到偶数项或是奇数项的公式然后直接算。
也可以直接两种转移矩阵写出来
假设A,B分别是奇数和偶数的转移矩阵,虽然他们是交替的,我们不能直接用快速幂,但是可以利用结合律,将BA看做整体算。本质和先算出偶数项公式一样。

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<map>
#include<queue>
#include<bitset>
#include<cmath>
#include<set>
#include<unordered_map>
#define fo(i,a,b) for (ll (i)=(a);(i)<=(b);(i)++)
#define fd(i,b,a) for (ll (i)=(b);(i)>=(a);(i)--)
#define mk(x,y) make_pair((x),(y))
//#define A puts("Yes")
//#define B puts("No")
using namespace std;
typedef double db;
typedef long long ll;
//typedef __int128 i128;
const int N=1e6+5;
const ll inf = 1ll << 60;
//const ll mo=1000000007;
ll m,n;
struct mat{
	ll a[3][3];
	void init() {
		memset(a,0,sizeof(a));
	}
	friend mat operator * (const mat &a,const mat &b) {
		mat c;
		c.init();
		fo(i,1,2) fo(j,1,2) fo(k,1,2) {
			c.a[i][j]+=a.a[i][k]*b.a[k][j]%m;
			c.a[i][j]%=m;
		}
		return c;
	}
	void print(){
		fo(i,1,2) {
			fo(j,1,2) printf("%lld ",a[i][j]);
			printf("\n");
		}
	}
}; 
//ll power(ll a,ll b){
//	ll t=1,y=a;
//	while (b) {
//		if (b&1) t=t*y%m;
//		y=y*y%mo;
//		b/=2;
//	}
//	return t;
//}
void solve(ll b){
	mat t,y;
	t.init();
	y.init();
	t.a[2][1]=1;
	y.a[1][1]=4; y.a[1][2]=2; y.a[2][2]=1;
	
	while (b) {
		if (b&1) t=y*t;
		y=y*y;
		b/=2;
	}
	
	ll ans=t.a[1][1];
	if (n&1) ans=(ans*2ll+1ll)%m;
	printf("%lld\n",ans);
}
int main()
{
//	freopen("data.in","r",stdin);

	while (scanf("%lld %lld",&n,&m)!=EOF) {
		solve(n/2);
	}

	return 0;
}


	
posted @ 2024-01-15 15:22  gan_coder  阅读(15)  评论(0)    收藏  举报