codeforces-1182-E-Product Oriented Recurrence(矩阵快速幂+欧拉降幂)

上篇博客就是在写这篇题解的时候发现公式预览不好用弄出来的23333

题目链接:https://codeforces.com/contest/1182/problem/E

题目大意:

定义一个函数
$f_x=c^{2x-6}*f_{x-1}*f_{x-2}*f_{x-3}$ for $x\geq4$ , $f_1,f_2,f_3$是已知的,求$f_nmod(1e9+7)$

思路

乍一看感觉是矩阵快速幂,但是递推关系不是线性的没法写呀,然后我们可以发现每一项的指数是满足线性递推关系的

$f_4=c^2 \cdot f_1 \cdot f_2 \cdot f_3$
$f_5=c^{4+2} \cdot f_1 \cdot f_2^2 \cdot f_3^2$
$f_5=c^{6+6+2} \cdot f_1^2 \cdot f_2^3 \cdot f_3^4$
a然后不难看从$f_6$之后$f_1,f_2,f_3$的指数都是前三项的和,设$f_n$中的$f_1$的指数是$t_n$,则$$t_n=t_{n-1}+t_{n-2}+t_{n-3}$$
$f_2,f_3$的指数同理,这就可以构建一个矩阵了

$$\begin{pmatrix}
{t_{n-3}}&{t_{n-2}}&{t_{n-1}}
\end{pmatrix} \begin{pmatrix} 0&0&1\\ 1&0&1\\ 0&1&1\end{pmatrix}
\begin{pmatrix} t_{n-2}&t_{n-1}&t_n \end{pmatrix}$$

且$f_1$的$t_1=1,t_2=1,t_3=2$$f_2$的$t_1=1,t_2=2,t_3=3$$f_3$的$t_1=1,t_2=1,t_3=4$
然后是$C$的指数,设$C$的指数是$k$,则从$f_4$开始算$k_1=2,k_2=6,k_3=14$
$$k_n=k_{n-1}+k_{n-2}+k_{n-3}+2 \cdot n$$

$$k_n=k_{n-1}+k_{n-2}+k_{n-3}+2 \cdot (n-1)+2$$
构造矩阵:
$$\begin{pmatrix}
{k_{n-3}}&{k_{n-2}}&{k_{n-1}}&{2 \cdot (n-1)}&{2}
\end{pmatrix} \begin{pmatrix} 0&0&1&0&0\\ 1&0&1&0&0\\ 0&1&1&0&0\\0&0&1&1&0\\ 0&0&1&1&1\end{pmatrix}
\begin{pmatrix} k_{n-2}&k_{n-1}&k_n&2 \cdot n,2 \end{pmatrix}$$
然后矩阵快速幂算的是指数,所以根据欧拉降幂,要对1e9+7的欧拉函数值取模,也就是对1e9+6取模
最后算完指数做快速幂算最后的答案就可以了

AC代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
typedef long long ll;
#define wfor(i,j,k) for(i=j;i<k;++i)
#define mfor(i,j,k) for(i=j;i>=k;--i)
// void read(ll &x) {
// char ch = getchar(); x = 0;
// for (; ch < '0' || ch > '9'; ch = getchar());
// for (; ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';
// }
const ll mod=1e9+6;
const ll mod2=1e9+7;
struct Matix
{
ll ma[5][5];
};
Matix mul(Matix a,Matix b,ll n)
{
ll i,j,k;
Matix c;
memset(c.ma,0,sizeof(c.ma));
wfor(i,0,n)
{
wfor(j,0,n)
{
wfor(k,0,n)
{
c.ma[i][j]=(c.ma[i][j]+(a.ma[i][k]*b.ma[k][j]%mod))%mod;
}
}
}
return c;
}
Matix ksm(Matix a,ll b,ll n)
{
Matix ans;
memset(ans.ma,0,sizeof(ans.ma));
ll i;
wfor(i,0,n)
{
ans.ma[i][i]=1;
}
while(b)
{
if(b&1)
ans=mul(ans,a,n);
a=mul(a,a,n);
b>>=1;
}
return ans;
}
ll ksm_num(ll a,ll b)
{
ll ans=1;
while(b)
{
if(b&1)
{
ans=ans*a%mod2;
}
a=a*a%mod2;
b>>=1;
}
return ans;
}
int main()
{
std::ios::sync_with_stdio(false);
#ifdef test
freopen("F:\\Desktop\\question\\in.txt","r",stdin);
#endif
#ifdef ubuntu
freopen("/home/time/debug/debug/in","r",stdin);
freopen("/home/time/debug/debug/out","w",stdout);
#endif
ll n, f1,f2,f3,c;
cin>>n>>f1>>f2>>f3>>c;
Matix ori={{{0,0,1},{1,0,1},{0,1,1}}};
Matix F1={{{1,1,2}}};
Matix F2={{{1,2,3}}};
Matix F3={{{1,2,4}}};
Matix C={{{2,6,14,6,2}}};
Matix C_ori={{{0,0,1,0,0},{1,0,1,0,0},{0,1,1,0,0},{0,0,1,1,0},{0,0,1,1,1}}};
ll res=0;
if(n>=7)
{
n-=6;
Matix temp=ksm(ori,n,3);
Matix ans=mul(F1,temp,3);//算f1的指数
res=ksm_num(f1,ans.ma[0][2]);
ans=mul(F2,temp,3);//算f2的指数
res=res*ksm_num(f2,ans.ma[0][2])%mod2;
ans=mul(F3,temp,3);//算f3的指数
res=res*ksm_num(f3,ans.ma[0][2])%mod2;
temp=ksm(C_ori,n,5);
ans=mul(C,temp,5);//算c的指数
res=res*ksm_num(c,ans.ma[0][2])%mod2;
cout<<res<<endl;
}else
{
n-=4;
res=ksm_num(f1,F1.ma[0][n])%mod2;
res=res*ksm_num(f2,F2.ma[0][n])%mod2;
res=res*ksm_num(f3,F3.ma[0][n])%mod2;
res=res*ksm_num(c,C.ma[0][n])%mod2;
cout<<res<<endl;
}
return 0;
}

本文标题:codeforces-1182-E-Product Oriented Recurrence(矩阵快速幂+欧拉降幂)

文章作者:

发布时间:2019年09月25日 - 20:09

最后更新:2019年10月23日 - 20:10

原始链接:http://startcraft.cn/post/699fa364.html

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

-------------The End-------------