码迷,mamicode.com
首页 > 其他好文 > 详细

HDU4686 Arc of Dream 矩阵

时间:2017-11-10 23:10:24      阅读:262      评论:0      收藏:0      [点我收藏+]

标签:hdu   传送门   while   jpg   pac   puts   ace   cpp   style   

欢迎访问~原文出处——博客园-zhouzhendong

去博客园看该题解


题目传送门 - HDU4686


题意概括

  技术分享

  a0 = A0
  ai = ai-1*AX+AY
  b0 = B0
  bi = bi-1*BX+BY

  求AoD(n)

  n=0时答案为0!!!!


题解

  具体的矩阵构建思路指导可以参考例题链接

  这里仅提供运算过程。

  Ai=Ai-1*AX+AY

  Bi=Bi-1*BX+BY

  AiBi=(Ai-1*AX+AY)(Bi-1*BX+BY)

        =AX*BX*Ai-1*Bi-1+AX*BY*Ai-1+BX*AY*Bi-1+AY*BY

 

        Si           AiBi       Ai     Bi        K

Si-1            1     0       0    0     0

Ai-1Bi-1     AX*BX   AX*BX     0    0     0

Ai-1         AX*BY   AX*BY       AX     0     0

Bi-1          BX*AY   BX*AY      0     BX    0

K          AY*BY   AY*BY       AY    BY    1

  初始矩阵:

  S0        A0B0       A0     B0   K

  A0*B0       A0*B0           A0     B0     1


代码

#include <cstring>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <cstdlib>
using namespace std;
typedef long long LL;
const LL mod=1000000007,m=5;
LL n,A0,AX,AY,B0,BX,BY;
struct Mat{
	LL v[m][m];
	Mat (){}
	Mat (LL x){
		(*this).set(x);
	}
	void set(LL x){
		memset(v,0,sizeof v);
		if (x==1)
			for (int i=0;i<m;i++)
				v[i][i]=1;
	}
	Mat operator * (Mat x){
		Mat ans(0);
		for (int i=0;i<m;i++)
			for (int j=0;j<m;j++)
				for (int k=0;k<m;k++)
					ans.v[i][j]=(ans.v[i][j]+v[i][k]*x.v[k][j])%mod;
		return ans;
	}
	void operator *= (Mat x){
		(*this)=(*this)*x;
	}
}M,Md;
Mat MatPow(Mat x,LL y){
	Mat ans(1),now=x;
	while (y){
		if (y&1LL)
			ans*=now;
		now*=now;
		y>>=1;
	}
	return ans;
}
int main(){
	while (~scanf("%lld%lld%lld%lld%lld%lld%lld",&n,&A0,&AX,&AY,&B0,&BX,&BY)){
		if (!n){
			puts("0");
			continue;
		}
		A0%=mod,AX%=mod,AY%=mod,B0%=mod,BX%=mod,BY%=mod;
		LL NewArr[m][m]={{1         ,0         ,0  ,0  ,0},
						 {AX*BX%mod ,AX*BX%mod ,0  ,0  ,0},
						 {AX*BY%mod ,AX*BY%mod ,AX ,0  ,0},
						 {BX*AY%mod ,BX*AY%mod ,0  ,BX ,0},
						 {AY*BY%mod ,AY*BY%mod ,AY ,BY ,1}};
		LL NewArr2[m]=	 {A0*B0%mod ,A0*B0%mod ,A0 ,B0 ,1};
		memcpy(Md.v,NewArr,sizeof NewArr);
		memcpy(M.v[0],NewArr2,sizeof NewArr2);
		Md=MatPow(Md,n-1);
		M*=Md;
		printf("%lld\n",M.v[0][0]);
	}
	return 0;
}

  

 

HDU4686 Arc of Dream 矩阵

标签:hdu   传送门   while   jpg   pac   puts   ace   cpp   style   

原文地址:http://www.cnblogs.com/zhouzhendong/p/7816724.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!