Sequence
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 1725 Accepted Submission(s): 651
Problem Description
Let us define a sequence as below
Your job is simple, for each task, you should output Fn module 109+7.
Input
The first line has only one integer T, indicates the number of tasks.
Then, for the next T lines, each line consists of 6 integers, A , B, C, D, P, n.
1≤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
赛场上真搞笑,居然以为能推出个公式,下来看题解原来是区间矩阵快速幂
要用二分查找区间的右边界,如果遍历过去找,会超时,求mid要向上取整,不然二分会死循环
转载:https://blog.csdn.net/LinzhiQQQ/article/details/81662585
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int inf = 0x3f3f3f3f;
const LL mod = 1e9 + 7;
LL res[5];
typedef struct Matrix{
LL mp[3][3];
Matrix(){
memset(mp,0,sizeof(mp));
}
void init(){
mp[0][0] = mp[1][1] = mp[2][2] = 1;
}
//重载结构体的乘运算符
Matrix operator *(Matrix &p){
Matrix ans;
for(int i = 0;i < 3;++i)
{
for(int j = 0;j < 3;++j)
{
for(int k = 0;k < 3;++k){
ans.mp[i][j] = (ans.mp[i][j] + mp[i][k] * p.mp[k][j] % mod) % mod;
}
ans.mp[i][j] %= mod;
}
}
return ans;
}
}Matrix;
Matrix x;
Matrix pow_mod(Matrix p,int m)
{
Matrix ans;
ans.init();
while(m)
{
if(m & 1) ans = ans * p;
p = p * p;
m >>= 1;
}
return ans;
}
LL getqujian(LL i,LL n,LL p)
{
LL num = p / i;
LL l = i,r = n;
while(l < r)
{
//cout << l << " " << r << endl;
//向上取整
LL mid = (r + l + 1) / 2;
//cout << r << endl;
//printf("l:%lld r:%lld mid:%lld\n",l,r,mid);
if((p / mid) == num){
l = mid;
}else if((p / mid) < num){
r = mid - 1;
}
else{
l = mid + 1;
}
}
return l;
}
int main()
{
LL a,b,c,d,p,n;
int t;
scanf("%d",&t);
while(t--)
{
scanf("%lld %lld %lld %lld %lld %lld",&a,&b,&c,&d,&p,&n);
res[1] = a;
res[2] = b;
if(n <= 2){
printf("%lld\n",res[n]);
continue;
}
memset(x.mp,0,sizeof(x.mp));
x.mp[0][0] = d;x.mp[1][0] = c;
x.mp[0][1] = 1;x.mp[2][2] = 1;
LL f1 = res[2],f2 = res[1];
for(LL i = 3;i <= n;)
{
LL l = i;
LL r = getqujian(i,n,p);
//cout << r << endl;
x.mp[2][0] = p / i;
//cout << r << endl;
Matrix ans = pow_mod(x,r - l + 1);
//cout << 1 << endl;
res[3] = (f1 * ans.mp[0][0] % mod + f2 * ans.mp[1][0] % mod + ans.mp[2][0]) % mod;
res[4] = (f1 * ans.mp[0][1] % mod + f2 * ans.mp[1][1] % mod + ans.mp[2][1]) % mod;
f1 = res[3];
f2 = res[4];
//cout << p << endl;
i = r + 1;
//cout << i << endl;
}
printf("%lld\n",f1);
}
return 0;
}