HDU6395-Sequence 矩阵快速幂+除法分块
Posted cwolf9
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU6395-Sequence 矩阵快速幂+除法分块相关的知识,希望对你有一定的参考价值。
目录
(有任何问题欢迎留言或私聊 && 欢迎交流讨论哦
Catalog
Problem:Portal传送门
?原题目描述在最下面。
Solution:
?一看矩阵快速幂,再一看怎么多一个变项?(? frac{p}{n}?)?
?我去,(? frac{p}{n}?)这不是前几天写过的一道除法分块经典题吗?
?关于除法分块,请看这里:GYM101652
?然后,就没有然后了~
AC_Code:
#include<bits/stdc++.h>
#define mme(a,b) memset((a),(b),sizeof((a)))
using namespace std;
typedef long long LL;
const int MXN = 5e5+7;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
int n;
LL A,B,C,D,P;
struct lp{
LL ar[3][3];
}aa,bb,cc;
lp multi(lp a,lp b){
lp c;
memset(c.ar,0,sizeof(c.ar));
for(int k = 0; k < 3; ++k){
for(int i = 0; i < 3; ++i){
for(int j = 0; j < 3; ++j){
c.ar[i][j] += a.ar[i][k]*b.ar[k][j];
if(c.ar[i][j]>=MOD)c.ar[i][j] %= MOD;
}
}
}
return c;
}
lp ksm(lp a,LL b){
lp res;
for(int i = 0; i < 3; ++i){
for(int j = 0; j < 3; ++j){
res.ar[i][j] = (i==j);
}
}
while(b){
if(b&1)res = multi(res,a);
a = multi(a, a);
b>>=1;
}
return res;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("E://ADpan//in.in", "r", stdin);
//freopen("E://ADpan//out.out", "w", stdout);
#endif
int tc = 0;
int tim;
scanf("%d", &tim);
while(tim--){
scanf("%lld%lld%lld%lld%lld%d", &A,&B,&C,&D,&P,&n);
if(n == 1){
printf("%lld
", A);
continue;
}else if(n == 2){
printf("%lld
", B);
continue;
}else if(n == 3){
printf("%lld
", (B*D%MOD+A*C%MOD+P/3)%MOD);
continue;
}
/*aa.ar[3][3] = {
{D,1LL,0LL},
{C,0LL,0LL},
{xLL,0LL,1LL},
};*/
memset(aa.ar,0,sizeof(aa.ar));
memset(bb.ar,0,sizeof(bb.ar));
aa.ar[0][0]=D;
aa.ar[1][0]=C;
aa.ar[0][1]=1;
aa.ar[2][2]=1;
bb.ar[0][0]=B;
bb.ar[0][1]=A;
bb.ar[0][2]=1;
/*bb.ar[3][3] = {
{B,A,1},
};*/
//这是参考大佬的写法一
for(LL l = 3, r; l <= n; l = r + 1){
if(P/l) r = min(P/(P/l),n*1LL);
else r = n;
aa.ar[2][0] = P/l;
cc = ksm(aa, r-l+1);
bb = multi(bb, cc);
}
/*这是我本来繁琐的写法
for(LL l = 3, r; l <= P; l = r + 1){
r = min(P/(P/l),n*1LL);
aa.ar[2][0] = P/l;
cc = ksm(aa, r-l+1);
bb = multi(bb, cc);
if(r == n * 1LL)break;
}
if(P <= n - 1){
LL m = n - (P+1)+1;
aa.ar[2][0] = 0;
if(P<3)m = n-2;
cc = ksm(aa, m);
bb = multi(bb, cc);
}*/
printf("%lld
", bb.ar[0][0]);
}
return 0;
}
Problem Description:
以上是关于HDU6395-Sequence 矩阵快速幂+除法分块的主要内容,如果未能解决你的问题,请参考以下文章
HDU 5895 Mathematician QSC(矩阵乘法+循环节降幂+除法取模小技巧+快速幂)
HDU 5895 Mathematician QSC(矩阵乘法+循环节降幂+除法取模小技巧+快速幂)——2016 ACM/ICPC Asia Regional Shenyang Online