Arc of Dream
Time Limit: 2000/2000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)Total Submission(s): 2452 Accepted Submission(s): 753
where
a0 = A0
ai = ai-1*AX+AY
b0 = B0
bi = bi-1*BX+BY
What is the value of AoD(N) modulo 1,000,000,007?
Each test case contains 7 nonnegative integers as follows:
N
A0 AX AY
B0 BX BY
N is no more than 1018, and all the other integers are no more than 2×109.
這道題是比較難的矩陣構造題。不過通過之前做的那幾道和本題相似的矩陣題。我們也可以掌握一定的矩陣構造技巧。因而構造出合適的矩陣還是很容易的。
參考代碼:(利用分塊矩陣求解,當然也可以用二分矩陣多項式+矩陣快速冪)
代碼略醜,用的時間也稍微長一些。
#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<queue>
#include<ctime>
#include<cstdlib>
#include<iomanip>
#include<utility>
#define pb push_back
#define mp make_pair
#define CLR(x) memset(x,0,sizeof(x))
#define _CLR(x) memset(x,-1,sizeof(x))
#define REP(i,n) for(int i=0;i<n;i++)
#define Debug(x) cout<<#x<<"="<<x<<" "<<endl
#define REP(i,l,r) for(int i=l;i<=r;i++)
#define rep(i,l,r) for(int i=l;i<r;i++)
#define RREP(i,l,r) for(int i=l;i>=r;i--)
#define rrep(i,l,r) for(int i=1;i>r;i--)
#define read(x) scanf("%d",&x)
#define put(x) printf("%d\n",x)
#define ll long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<11
using namespace std;
const int MOD=1000000000+7;
ll n,a0,ax,ay,b0,bx,by;
struct mat
{
ll d[4][4];
}A,B,E1;
struct Mat
{
mat m[2][2];
}M,E;
mat multi(mat a,mat b)
{
mat ans;
rep(i,0,4)
{
rep(j,0,4)
{
ans.d[i][j]=0;
rep(k,0,4)
if(a.d[i][k]&&b.d[k][j])
ans.d[i][j]+=a.d[i][k]*b.d[k][j];
if(ans.d[i][j]>=MOD)
ans.d[i][j]%=MOD;
}
}
return ans;
}
mat add(mat a,mat b)
{
mat ans;
rep(i,0,4)
{
rep(j,0,4)
{
ans.d[i][j]=a.d[i][j]+b.d[i][j];
if(ans.d[i][j]>=MOD)
ans.d[i][j]%=MOD;
}
}
return ans;
}
Mat Multi(Mat a,Mat b)
{
Mat ans;
CLR(ans.m);
rep(i,0,2)
rep(j,0,2)
rep(k,0,2)
ans.m[i][j]=add(ans.m[i][j],multi(a.m[i][k],b.m[k][j]));
return ans;
}
mat quickmulti(Mat a,ll n)
{
if(n==0) return E.m[0][1];
if(n==1) return a.m[0][1];
Mat ans=E;
while(n)
{
if(n&1)
{
n--;
ans=Multi(ans,a);
}
else
{
n>>=1;
a=Multi(a,a);
}
}
return ans.m[0][1];
}
int main()
{
CLR(E1.d);CLR(E.m);
rep(i,0,4)
E1.d[i][i]=1;
rep(i,0,2)
rep(j,0,4)
E.m[i][i].d[j][j]=1;
while(~scanf("%I64d",&n))
{
scanf("%I64d%I64d%I64d%I64d%I64d%I64d",&a0,&ax,&ay,&b0,&bx,&by);
if(n==0)
{
printf("0\n");
continue;
}
A.d[0][0]=ax*bx%MOD;A.d[0][1]=ax*by%MOD;A.d[0][2]=ay*bx%MOD;A.d[0][3]=ay*by%MOD;
A.d[1][0]=0;A.d[1][1]=ax%MOD;A.d[1][2]=0;A.d[1][3]=ay%MOD;
A.d[2][0]=0;A.d[2][1]=0;A.d[2][2]=bx%MOD;A.d[2][3]=by%MOD;
A.d[3][0]=0;A.d[3][1]=0;A.d[3][2]=0;A.d[3][3]=1;
CLR(B.d);
B.d[0][0]=a0*b0%MOD;B.d[1][0]=a0%MOD;B.d[2][0]=b0%MOD;B.d[3][0]=1;
Mat M;
CLR(M.m);
M.m[0][0]=E1;M.m[0][1]=M.m[1][1]=A;
mat ans=quickmulti(M,n-1);
ans=add(ans,E1);
ans=multi(ans,B);
printf("%I64d\n",ans.d[0][0]);
}
}