1. 程式人生 > >JLOI 2015--有意義的字符串(矩陣乘法)

JLOI 2015--有意義的字符串(矩陣乘法)

fine [1] ons tor http long clas 公式 per

知道公式就不難了系列。。。

感覺吉林省選好變態。。。這還只是第一題呀。。。

%dalaoPoPoQQQ。。。

看了大佬的題解。。。懵逼了一晚。。。

今天早上的時候終於想明白了!!!

於是飛快地A過此題。。。

題意

B 君有兩個好朋友,他們叫寧寧和冉冉。有一天,冉冉遇到了一個有趣的題目:輸入 b;d;n,求

技術分享

註意:其中 0<b^2< = d<(b+1)^2< = 10^18, n< = 10^18,並且 b mod 2=1,d mod 4=1

Solution

構造特征方程。。。構造矩陣。。。全靠YY(mdzz。。。

公式推導直接點下面的鏈接吧。。。特殊字符好難打。。。

再次%dalaoPoPoQQQ。。。

公式之後還要註意mod的值很大要用unsigned long long。。。

還有乘法要用快速乘,直接乘會爆炸。。。

想通了公式後再做這題就不難了。。。

代碼

#include<iostream>
#include<cstdio>
#define LL long long
#define ULL unsigned long long
#define mod 7528443412579576937
using namespace std;
ULL qui(ULL a,ULL b){
	ULL s=0;
	while(b){
		if(b&1)
		    s=(s+a)%mod;
		b>>=1;
		a=(a+a)%mod;
	}
	return s;
}
struct jz{
	ULL x[2][2];
	friend jz operator *(const jz &a,const jz &b){
		jz tmp;
		for(int i=0;i<2;i++)
			for(int j=0;j<2;j++){
				tmp.x[i][j]=0;
				for(int k=0;k<2;k++)
				    tmp.x[i][j]=(tmp.x[i][j]+qui(a.x[i][k],b.x[k][j]))%mod;
			}
		return tmp;
	}
}A,T;
void pow(ULL z){
	while(z){
		if(z&1)
		    T=T*A;
		z>>=1;
		A=A*A;
	}
}
int main(){
	ULL b,d,n,b2,f=0;
	cin>>b>>d>>n;
	if(n==0){
		printf("1\n");
		return 0;
	}
	b2=qui(b,b);
	A.x[0][0]=b;A.x[0][1]=1;A.x[1][0]=((d-b2)/4)%mod;A.x[1][1]=0;
	T.x[0][0]=b;T.x[0][1]=2;T.x[1][0]=0;T.x[1][1]=0;
	pow(n-1);
	if(d!=b2&&n%2==0) f=1;
	T.x[0][0]=(T.x[0][0]-f+mod)%mod;
	cout<<T.x[0][0]<<endl;
	return 0;
}

This passage is made by Yukino.

JLOI 2015--有意義的字符串(矩陣乘法)