BZOJ3240: [Noi2013]矩阵游戏

9 篇文章 0 订阅

http://www.lydsy.com/JudgeOnline/problem.php?id=3240

Description

婷婷是个喜欢矩阵的小朋友,有一天她想用电脑生成一个巨大的n行m列的矩阵(你不用担心她如何存储)。她生成的这个矩阵满足一个神奇的性质:若用F[i][j]来表示矩阵中第i行第j列的元素,则F[i][j]满足下面的递推式:

F[1][1]=1
F[i,j]=a*F[i][j-1]+b (j!=1)
F[i,1]=c*F[i-1][m]+d (i!=1)
递推式中a,b,c,d都是给定的常数。

现在婷婷想知道F[n][m]的值是多少,请你帮助她。由于最终结果可能很大,你只需要输出F[n][m]除以1,000,000,007的余数。



n,m太大,模(mod-2)  费马小定理。

推通项讨论。。恶心死人。MOD更恶心死。

另外:贴吧大神说矩阵也满足费马小定理?(亟待验证)

http://tieba.baidu.com/p/2472273208


/*直接推通项。矩阵不好做的。*/
#include <cstdio>
#include <cstring>
#include <algorithm>
typedef long long LL;
const LL MOD=1000000007LL;
void getMOD(char *a,LL &A,bool p){
	LL mod=MOD-p;
	int len=strlen(a);
	for (int i=0;i<len;++i)
		A=((A<<3)+(A<<1)+a[i]-'0')%mod;
	A=(A+mod)%mod;
}
LL power(LL a,LL b){
	LL res=1;
	for (;b;a=a*a%MOD,b>>=1)
		if (b&1) (res*=a)%=MOD;
	return res;
}
char TN[1000050],TM[1000050];
LL n,m,a,b,c,d;
LL Fn1,Fnm;
int main(){
	scanf("%s %s %lld %lld %lld %lld",TN,TM,&a,&b,&c,&d);
	if (a==1&&c==1){
		getMOD(TN,n,0),getMOD(TM,m,0);
		Fnm=((((n-1+MOD)%MOD)*((m-1+MOD)%MOD)%MOD)*(b*c%MOD)%MOD+(((n-1+MOD)%MOD)*d)%MOD+(((m-1+MOD)%MOD)*b)%MOD+1+MOD)%MOD;
		printf("%lld\n",Fnm);
		return 0;
		}
	LL A,B;
	if (a==1){
		getMOD(TM,m,0);
		A=c;
		B=(((m-1+MOD)%MOD)*(b*c%MOD)%MOD+d)%MOD;
		}
	if (a!=1){
		getMOD(TM,m,1);
		A=c*power(a,(m-1+MOD-1)%(MOD-1))%MOD;
		B=((((b*c%MOD)*power((a-1+MOD)%MOD,MOD-2))%MOD*(power(a,(m-1+MOD-1)%(MOD-1))-1+MOD)%MOD)%MOD+d)%MOD;
		}
	//A!=1
	getMOD(TN,n,1);
	Fn1=(power(A,(n-1+MOD-1)%(MOD-1))+((power(A,(n-1+MOD-1)%(MOD-1))-1+MOD)%MOD*B)%MOD*power((A-1+MOD)%MOD,MOD-2)%MOD)%MOD;
	if (a==1) Fnm=(Fn1+((m-1+MOD)%MOD*b)%MOD)%MOD;
	if (a!=1) Fnm=((power(a,(m-1+MOD-1)%(MOD-1))*Fn1)%MOD+((power(a,(m-1+MOD-1)%(MOD-1))-1+MOD)%MOD*b)%MOD*power((a-1+MOD)%MOD,MOD-2)%MOD)%MOD;
	printf("%lld\n",Fnm);
}


/*直接推通项。矩阵不好做的。*/#include <cstdio>#include <cstring>#include <algorithm>typedef long long LL;const LL MOD=1000000007LL;void getMOD(char *a,LL &A,bool p){LL mod=MOD-p;int len=strlen(a);for (int i=0;i<len;++i)A=((A<<3)+(A<<1)+a[i]-'0')%mod;A=(A+mod)%mod;}LL power(LL a,LL b){LL res=1;for (;b;a=a*a%MOD,b>>=1)if (b&1) (res*=a)%=MOD;return res;}char TN[1000050],TM[1000050];LL n,m,a,b,c,d;LL Fn1,Fnm;int main(){scanf("%s %s %lld %lld %lld %lld",TN,TM,&a,&b,&c,&d);if (a==1&&c==1){getMOD(TN,n,0),getMOD(TM,m,0);Fnm=((((n-1+MOD)%MOD)*((m-1+MOD)%MOD)%MOD)*(b*c%MOD)%MOD+(((n-1+MOD)%MOD)*d)%MOD+(((m-1+MOD)%MOD)*b)%MOD+1+MOD)%MOD;printf("%lld\n",Fnm);return 0;}LL A,B;if (a==1){getMOD(TM,m,0);A=c;B=(((m-1+MOD)%MOD)*(b*c%MOD)%MOD+d)%MOD;}if (a!=1){getMOD(TM,m,1);A=c*power(a,(m-1+MOD-1)%(MOD-1))%MOD;B=((((b*c%MOD)*power((a-1+MOD)%MOD,MOD-2))%MOD*(power(a,(m-1+MOD-1)%(MOD-1))-1+MOD)%MOD)%MOD+d)%MOD;}//A!=1getMOD(TN,n,1);Fn1=(power(A,(n-1+MOD-1)%(MOD-1))+((power(A,(n-1+MOD-1)%(MOD-1))-1+MOD)%MOD*B)%MOD*power((A-1+MOD)%MOD,MOD-2)%MOD)%MOD;if (a==1) Fnm=(Fn1+((m-1+MOD)%MOD*b)%MOD)%MOD;if (a!=1) Fnm=((power(a,(m-1+MOD-1)%(MOD-1))*Fn1)%MOD+((power(a,(m-1+MOD-1)%(MOD-1))-1+MOD)%MOD*b)%MOD*power((a-1+MOD)%MOD,MOD-2)%MOD)%MOD;printf("%lld\n",Fnm);}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值