http://acm.hdu.edu.cn/showproblem.php?pid=4686
多校的第9场比赛,这题是这场比赛中的第一题,似乎是一道签到题,不过,我第一眼看到,深深地表示不会,唯一想到的就是想去寻找它的循环,然后就YY去做它了。好在lele犀利的发现了它是一道矩阵题(表示矩阵做得很少,线代接近白学,orz),然后lele果断敲掉了它。
好吧,赛后在acmood学长的教导下,我自己敲了一个。
思路 : 够造出一个二维矩阵A来,使得A × [ai * bi ai bi 1 S(i)] = [a(i+1) * b(i+1) a(i+1) b(i+1) 1 S(i+1)]来,然后就是对于A矩阵做幂运算(二进制优化下)即可了。
//cnwsycf
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
#include <queue>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
typedef __int64 LL;
const int INF = 1<<29;
const int mod = 1000000007;
const int maxn = 1005;
#define MAX(a,b) (a > b ? a : b)
#define MIN(a,b) (a > b ? b : a)
struct node
{
LL aa[5][5];
}dd[64];
struct diaosi
{
LL bb[5];
}ans;
bool bit[64];
LL N,a,A,B,b,C,D,M;
void init()
{
memset(dd,0,sizeof(dd));
dd[0].aa[0][0] = (A % mod) * (C % mod) % mod;
dd[0].aa[0][1] = (A % mod) * (D % mod) % mod;
dd[0].aa[0][2] = (B % mod) * (C % mod) % mod;
dd[0].aa[0][3] = (B % mod) * (D % mod) % mod;
dd[0].aa[1][1] = (A % mod);
dd[0].aa[1][3] = (B % mod);
dd[0].aa[2][2] = (C % mod);
dd[0].aa[2][3] = (D % mod);
dd[0].aa[3][3] = 1;
dd[0].aa[4][0] = (A % mod) * (C % mod) % mod;
dd[0].aa[4][1] = (A % mod) * (D % mod) % mod;
dd[0].aa[4][2] = (B % mod) * (C % mod) % mod;
dd[0].aa[4][3] = (B % mod) * (D % mod) % mod;
dd[0].aa[4][4] = 1;
ans.bb[0] = (a % mod) * (b % mod) % mod;
ans.bb[1] = a % mod;
ans.bb[2] = b % mod;
//for (int i=0;i<4;i++)ans.bb[i] = 1;
ans.bb[3] = 1;
ans.bb[4] = ans.bb[0];
LL tt = N - 1;
M = 0;
while (tt > 0)
{
bit[M++] = tt % 2;
tt /= 2;
}
return ;
}
void cheng(int x)
{
//node temp;
for (int i=0;i<5;i++)
for (int j=0;j<5;j++)
{
LL sum = 0;
for (int k=0;k<5;k++)
{
sum += (dd[x].aa[i][k] % mod) * (dd[x].aa[k][j] % mod);
sum %= mod;
}
dd[x+1].aa[i][j] = sum;
}
}
void bitcreate()
{
for (int i=0;i<M;i++)
{
cheng(i);
}
//memset(bit,0,sizeof(bit))
//for (int i=0;i<M;i++)printf("%d",bit[i]);printf("\n");
return ;
}
void xiangcheng(int x)
{
diaosi temp;
for (int i=0;i<5;i++)
{
LL sum = 0;
for (int j=0;j<5;j++)
{
sum += (dd[x].aa[i][j] % mod) * (ans.bb[j] % mod);
sum %= mod;
}
temp.bb[i] = sum;
}
ans = temp;
//for (int i=0;i<5;i++)printf("%d ",ans.bb[i]);printf("\n");
}
void show()
{
for (int k=0;k<M;k++)
{
for (int i=0;i<5;i++)
{
for (int j=0;j<5;j++)
printf("%d ",dd[k].aa[i][j]);
printf("\n");
}
printf("\n");
}
}
LL solve()
{
for (int i=0;i<M;i++)
{
if (bit[i])xiangcheng(i);
}
return ans.bb[4];
}
int main()
{
while (scanf("%I64d%I64d%I64d%I64d%I64d%I64d%I64d",&N,&a,&A,&B,&b,&C,&D) != EOF)
{
if (N == 0)
{
printf("0\n");
continue ;
}
init();
//show();
bitcreate();
//show();
LL sum = solve();
printf("%d\n",sum % mod);
}
return 0;
}