传送门----http://acm.hdu.edu.cn/showproblem.php?pid=6395
思路:由于有后半部分的下取整,可以联想到整除分块去做。再用矩阵快速幂优化递推即可。
Code:
//2
#include
#include
#include
#include
#define LL long long
using namespace std;
const LL mod = 1000000007;
LL a, b, c, d, p, n;
struct martix
{
LL m[4][4];
martix()
{
memset(m, 0, sizeof(m));
}
martix operator*(const martix b)const
{
LL i, j, k;
martix ans;
for(i = 1; i <= 3; i++)
for(j = 1; j <= 3; j++)
{
ans.m[i][j] = 0;
for(k = 1; k <= 3; k++)
{
ans.m[i][j] += m[i][k] * b.m[k][j];
ans.m[i][j] %= mod;
}
}
return ans;
}
};
void Debug (martix a)
{
for(int i = 1; i <= 3; i++)
{
for(int j = 1; j <= 3; j++)
cout << a.m[i][j] << ' ';
cout << endl;
}
}
martix martix_pow(LL n,LL x)
{
martix temp, res;
temp.m[1][1] = d;
temp.m[1][2] = c;
temp.m[1][3] = x;
temp.m[2][1] = 1;
temp.m[3][3] = 1;
res.m[1][1] = res.m[2][2] = res.m[3][3] = 1;
while(n)
{
if(n & 1)
res = res * temp;
temp = temp * temp;
n >>= 1;
}
return res;
}
int main()
{
int T;
scanf("%d", &T);
while(T--)
{
scanf("%lld%lld%lld%lld%lld%lld", &a, &b, &c, &d, &p, &n);
if(n == 1)
printf("%lld\n", a);
else if(n == 2)
printf("%lld\n", b);
else
{
martix A, B;
LL l, r;
A.m[1][1] = A.m[2][2] = A.m[3][3] = 1;
for(l = 3; l <= n; ++l)
{
r = (l <= p) ? min(p / (p / l), n) : n;
A = (martix_pow(r - l + 1,p/l))*A;
l=r;
// Debug(A);
}
printf("%lld\n",(A.m[1][1]*b%mod+A.m[1][2]*a%mod+A.m[1][3])%mod);
}
}
}