Let us define a sequence as below
⎧⎩⎨⎪⎪⎪⎪⎪⎪F1F2Fn===ABC⋅Fn−2+D⋅Fn−1+⌊Pn⌋{F1=AF2=BFn=C⋅Fn−2+D⋅Fn−1+⌊Pn⌋
Your job is simple, for each task, you should output FnFn module 109+7109+7.
Input
The first line has only one integer TT, indicates the number of tasks.
Then, for the next TT lines, each line consists of 66 integers, AA , BB, CC, DD, PP, nn.
1≤T≤200≤A,B,C,D≤1091≤P,n≤1091≤T≤200≤A,B,C,D≤1091≤P,n≤109
Sample Input
2 3 3 2 1 3 5 3 2 2 2 1 4
Sample Output
36 24
题不难,就是情况不太好处理,花费了不少时间代码:
#include<stdio.h>
#include<algorithm>
#include<iostream>
#include<string.h>
#include<math.h>
#include<bitset>
using namespace std;
#define ll long long
#define mod 1000000007
void mul(ll f[3],ll a[3][3])//模板
{
ll c[3];
memset(c,0,sizeof(c));
for(ll j=0; j<3; j++)
for(ll k=0; k<3; k++)
c[j]=(c[j]+(f[k]*a[k][j]+mod)%mod+mod)%mod;
memcpy(f,c,sizeof(c));
}
void mulself(ll a[3][3])//模板
{
ll c[3][3];
memset(c,0,sizeof(c));
for(ll i=0; i<3; i++)
for(ll j=0; j<3; j++)
for(ll k=0; k<3; k++)
c[i][j]=(c[i][j]+(a[i][k]*a[k][j]+mod)%mod+mod)%mod;
memcpy(a,c,sizeof(c));
}
void assignment(ll a[3][3],ll b[3][3])//分段每次都要给a重新赋值
{
for(ll i=0; i<3; i++)
for(ll j=0; j<3; j++)
a[i][j]=b[i][j];
}
int main()
{
ll t,A,B,C,D,p,n,m;
scanf("%lld",&t);
while(t--)
{
scanf("%lld%lld%lld%lld%lld%lld",&A,&B,&C,&D,&p,&n);
ll f[3]= {A,B},a[3][3],b[3][3]= {{0,C,0},{1,D,0},{0,1,1}};
if(n==1||n==2)//此情况不处理
;
else if(p>n)//p>n时的分段
{
for(ll l = 3, r; l <= n; l = r + 1)
{
r = min(n,p / (p / l)),m=(r-l+1),f[2]=p/l;
assignment(a,b);
for(; m; m>>=1)
{
if(m&1)
mul (f,a);
mulself(a);
}
}
}
else//p<n时的分段
{
for(ll l = 3, r; l <= p; l = r + 1)
{
r = p / (p / l),m=(r-l+1),f[2]=p/l;
assignment(a,b);
for(; m; m>>=1)
{
if(m&1)
mul (f,a);
mulself(a);
}
}
assignment(a,b);
m=n-max(p,2ll),f[2]=0;
for(; m; m>>=1)
{
if(m&1)
mul (f,a);
mulself(a);
}
}
printf("%lld\n",(f[1]+mod)%mod);//要用f[1],用f[0]时,f[1]的值就会变
}
return 0;
}