题目链接:
HDU 4686 Arc of Dream
题意:
给出 n,a0,ax,ay,b0,bx,by .且 a[i]=ax?a[i?1]+ay,b[i]=bx?b[i?1]+by.
定义 f[n]= ∑pk=0(a[k]?b[k])(其中p=n?1) .
求出 nmod(1e9+7) .
分析;
构造矩阵。想要由
* 1 1* a[i-1] a[i]* b[i-1] 得到 b[i]* a[i-1]*b[i-1] a[i]*b[i]* f[i-1] f[i]
1的出现是因为a[i]和b[i]的递推式中有常数项。
很容易得到矩阵
* 1 0 0 0 0* ay ax 0 0 0* A =by 0 bx 0 0* ay*by ax*by bx*ay ax*bx 0* ay*by ax*by bx*ay ax*bx 1
然后用矩阵快速幂结局就行啦。
注意:
当 n==0 时,结果是0.需要特判。我没注意,结果 TLE 了三发,白白改了一个多小时, too naive,o(╯□╰)o
//1580K 218MS
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <iostream>
using namespace std;
const long long mod=(long long)(1e9+7);long long n,a0,ax,ay,b0,bx,by;struct Matrix{int row,col;long long data[10][10];
};inline void init(Matrix& x)
{x.row=x.col=5;memset(x.data,0,sizeof(x.data));x.data[1][1]=x.data[5][5]=1;x.data[2][1]=ay,x.data[2][2]=ax,x.data[3][1]=by,x.data[3][3]=bx;x.data[4][1]=x.data[5][1]=ay*by%mod,x.data[4][2]=x.data[5][2]=ax*by%mod;x.data[4][3]=x.data[5][3]=bx*ay%mod,x.data[4][4]=x.data[5][4]=ax*bx%mod;
}inline Matrix multiply(Matrix a,Matrix b)
{Matrix ans;ans.row=a.row,ans.col=b.col;memset(ans.data,0,sizeof(ans.data));for(int i=1;i<=ans.row;i++){for(int j=1;j<=ans.col;j++){for(int k=1;k<=a.col;k++){ans.data[i][j]+=a.data[i][k]*b.data[k][j];ans.data[i][j]%=mod;}}}return ans;
}inline Matrix quick_power(Matrix a,long long n)
{Matrix ans,tmp=a,pre;ans.row=ans.col=pre.row=pre.col=a.row;memset(ans.data,0,sizeof(ans.data));for(int i=1;i<=ans.row;i++)ans.data[i][i]=1;while(n){if(n&1){ans=multiply(ans,tmp);}tmp=multiply(tmp,tmp);n>>=1;}return ans;
}int main()
{freopen("Sin.txt","r",stdin);while(~scanf("%I64d",&n)){scanf("%I64d %I64d %I64d",&a0,&ax,&ay);scanf("%I64d %I64d %I64d",&b0,&bx,&by);a0%=mod,ax%=mod,ay%=mod;b0%=mod,bx%=mod,by%=mod;if(n==0){printf("0\n");continue;}Matrix ans,tmp;init(ans);ans=quick_power(ans,n-1);tmp.row=5,tmp.col=1;tmp.data[1][1]=1,tmp.data[2][1]=a0,tmp.data[3][1]=b0;tmp.data[4][1]=tmp.data[5][1]=a0*b0%mod;tmp=multiply(ans,tmp);printf("%I64d\n",tmp.data[5][1]%mod);} return 0;
}