E. Product Oriented Recurrence(矩阵快速幂+欧拉降幂)

题目链接:

https://codeforces.com/contest/1182/problem/E

题目大意:

 f(x)=c^(2x−6)⋅f(x−1)⋅f(x−2)⋅f(x−3)    for x≥4x≥4.

给你f1,f2,f3,n,c。求第n项的结果。

具体思路:

看到递推式想到用矩阵快速幂优化;但是如果都是乘法的话,是无法化成矩阵相乘的形式的。然后就开始想怎么将乘法转换成加法。推了一个多小时也没有推出来。。

具体的解题过程如下:

对于每一项,这一项里面包含的f1 和 f2 和 f3 和 c 的 个数都是能由它前面的能通过加法的形式实现的,最终结果再将这些乘起来就好了。

第i项中f1的个数 = 第i-1项中f1的个数+第i-2项中f1的个数+第i-3项中f1的个数;

f2,f3同理。

第i项中c的个数 = 第i-1项中c的个数 + 第i-2项中c的个数 + 第i-3项中c的个数 + 2*i - 6;

(g[i],g[i-1],g[i-2])=(g[i-1],g[i-2],g[i-3])*

[1 1 0

1 0 1

1 0 0   ].

(f[i],f[i-1],f[i-2],g[i-3],i,1) = (f[i-1],f[i-2],f[i-3],i-1,1)*

[ 1 1 0 0 0

  1 0 1 0 0   

  1 0 0 0 0 

  2 0 0 1 0

  -4 0 0 1 1

]

注意这里的矩阵最终解出的结果是指数,也就是说模数并不是1e9+7.而应该是phi(1e9+7)=1e9+6.

AC代码:

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 const int maxn = 2e6+20;
  4 # define ll long long
  5 # define inf 0x3f3f3f3f
  6 const ll mod = 1e9+6;
  7 ll MD=mod+1;
  8 ll phi(ll x)
  9 {
 10     ll res=x,a=x;
 11     for(ll i=2; i*i<=x; i++)
 12     {
 13         if(a%i==0)
 14         {
 15             res=res/i*(i-1ll);
 16             while(a%i==0)
 17                 a/=i;
 18         }
 19     }
 20     if(a>1ll)
 21         res=res/a*(a-1ll);
 22     return res;
 23 }
 24 struct Matrix_First
 25 {
 26     ll a[5][5];
 27     Matrix_First operator *(Matrix_First b)
 28     {
 29         Matrix_First tmp;
 30         for(int i=1; i<=3; i++)
 31         {
 32             for(int j=1; j<=3; j++)
 33             {
 34                 tmp.a[i][j]=0;
 35                 for(int k=1; k<=3; k++)
 36                 {
 37                     tmp.a[i][j]=(tmp.a[i][j]+a[i][k]*b.a[k][j]%mod)%mod;
 38                     while(tmp.a[i][j]<0)
 39                         tmp.a[i][j]+=mod;// 这是求指数的过程
 40                     tmp.a[i][j]%=mod;
 41                 }
 42             }
 43         }
 44         return tmp;
 45     }
 46 } g1,g2,g3;
 47 struct Matrix_Second
 48 {
 49     ll a[6][6];
 50     Matrix_Second operator *(Matrix_Second b)
 51     {
 52         Matrix_Second tmp;
 53         for(int i=1; i<=5; i++)
 54         {
 55             for(int j=1; j<=5; j++)
 56             {
 57                 tmp.a[i][j]=0;
 58                 for(int k=1; k<=5; k++)
 59                 {
 60                     tmp.a[i][j]=(tmp.a[i][j]+a[i][k]*b.a[k][j]%mod)%mod;
 61                     while(tmp.a[i][j]<mod)
 62                         tmp.a[i][j]+=mod;
 63                     tmp.a[i][j]%=mod;
 64                 }
 65             }
 66         }
 67         return tmp;
 68     }
 69 } f;
 70
 71 Matrix_First qsm_First(Matrix_First t1,ll t2)
 72 {
 73     Matrix_First  ans=t1;
 74     t2--;
 75     while(t2)
 76     {
 77         if(t2&1)
 78             ans=ans*t1;
 79         t1=t1*t1;
 80         t2>>=1;
 81     }
 82     return ans;
 83 }
 84
 85 Matrix_Second qsm_Second(Matrix_Second t1,ll t2)
 86 {
 87     Matrix_Second  ans=t1;
 88     t2--;
 89     while(t2)
 90     {
 91         if(t2&1)
 92             ans=ans*t1;
 93         t1=t1*t1;
 94         t2>>=1;
 95     }
 96     return ans;
 97 }
 98
 99 ll qsm(ll t1,ll t2)
100 {
101     ll ans=1ll;
102     while(t2)
103     {
104         if(t2&1)
105             ans=ans*t1%MD;
106         t1=t1*t1%MD;
107         t2>>=1;
108     }
109     return ans;
110 }
111 int main()
112 {
113     ll n,f1,f2,f3,c;
114     scanf("%lld %lld %lld %lld %lld",&n,&f1,&f2,&f3,&c);
115     g1.a[1][1]=1;g1.a[1][2]=1;g1.a[1][3]=0;
116     g1.a[2][1]=1;g1.a[2][2]=0;g1.a[2][3]=1;
117     g1.a[3][1]=1;g1.a[3][2]=0;g1.a[3][3]=0;
118
119     g2.a[1][1]=1;g2.a[1][2]=1;g2.a[1][3]=0;
120     g2.a[2][1]=1;g2.a[2][2]=0;g2.a[2][3]=1;
121     g2.a[3][1]=1;g2.a[3][2]=0;g2.a[3][3]=0;
122
123     g3.a[1][1]=1;g3.a[1][2]=1;g3.a[1][3]=0;
124     g3.a[2][1]=1;g3.a[2][2]=0;g3.a[2][3]=1;
125     g3.a[3][1]=1;g3.a[3][2]=0;g3.a[3][3]=0;
126     g1=qsm_First(g1,(n-3ll));
127     g2=qsm_First(g2,(n-3ll));
128     g3=qsm_First(g3,(n-3ll));
129
130     ll num_1=g1.a[3][1];
131     ll num_2=g2.a[2][1];
132     ll num_3=g3.a[1][1];
133     f.a[1][1]=1;f.a[1][2]=1;f.a[1][3]=0;f.a[1][4]=0;f.a[1][5]=0;
134     f.a[2][1]=1;f.a[2][2]=0;f.a[2][3]=1;f.a[2][4]=0;f.a[2][5]=0;
135     f.a[3][1]=1;f.a[3][2]=0;f.a[3][3]=0;f.a[3][4]=0;f.a[3][5]=0;
136     f.a[4][1]=2;f.a[4][2]=0;f.a[4][3]=0;f.a[4][4]=1;f.a[4][5]=0;
137     f.a[5][1]=-4;f.a[5][2]=0;f.a[5][3]=0;f.a[5][4]=1;f.a[5][5]=1;
138     f=qsm_Second(f,n-3ll);
139     ll num_c=(3ll*f.a[4][1]+f.a[5][1]);
140     while(num_c<0)
141         num_c+=mod;
142     num_c%=mod;
143
144     ll ans=qsm(f1,num_1)%MD*qsm(f2,num_2)%MD;
145    // cout<<ans<<endl;
146     while(ans<0)
147         ans+=MD;
148     ans%=MD;
149     ans=ans*qsm(f3,num_3)%MD;
150    // cout<<ans<<endl;
151     while(ans<0)
152         ans+=MD;
153     ans%=MD;
154     ans=ans*qsm(c,num_c)%MD;
155    // cout<<ans<<endl;
156     while(ans<0)
157         ans+=MD;
158     ans%=MD;
159     printf("%lld\n",ans);
160     return 0;
161 }

原文地址:https://www.cnblogs.com/letlifestop/p/11011697.html

时间: 2024-10-08 14:26:01

E. Product Oriented Recurrence(矩阵快速幂+欧拉降幂)的相关文章

Product Oriented Recurrence(Codeforces Round #566 (Div. 2)E+矩阵快速幂+欧拉降幂)

传送门 题目 \[ \begin{aligned} &f_n=c^{2*n-6}f_{n-1}f_{n-2}f_{n-3}&\\end{aligned} \] 思路 我们通过迭代发现\(f_n\)其实就是由\(c^{x_1},f_1^{x_2},f_2^{x_3},f_3^{x_4}\)相乘得到,因此我们可以分别用矩阵快速幂求出\(x_1,x_2,x_3,x_4\),最后用快速幂求得答案. 对\(f_1,f_2,f_3\): \[ \begin{aligned} (x_n&&

HDU 3221 矩阵快速幂+欧拉函数+降幂公式降幂

装载自:http://www.cnblogs.com/183zyz/archive/2012/05/11/2495401.html 题目让求一个函数调用了多少次.公式比较好推.f[n] = f[n-1]*f[n-2].然后a和b系数都是呈斐波那契规律增长的.需要先保存下来指数.但是太大了.在这里不能用小费马定理.要用降幂公式取模.(A^x)%C=A^(x%phi(C)+phi(C))%C(x>=phi(C)) Phi[C]表示不大于C的数中与C互质的数的个数,可以用欧拉函数来求. 矩阵快速幂也不

hdu 5895(矩阵快速幂+欧拉函数)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5895 f(n)=f(n-2)+2*f(n-1) f(n)*f(n-1)=f(n-2)*f(n-1)+2*f(n-1)*f(n-1); 2*f(n-1)*f(n-1)=f(n)*f(n-1)-f(n-2)*f(n-1); 累加可得 g(n) = f(n)*f(n+1)/2 然后这个公式:A^x % m = A^(x%phi(m)+phi(m)) % m (x >= phi(m)) 反正比赛没做出来.

BZOJ1408 NOI2002 Robot 快速幂+欧拉函数

题意:分别求所有质因数都不同且质因数个数为奇数个.偶数个的数的欧拉函数和,和质因数存在重复的数的欧拉函数和 题解: 说书题……前面一大串就是用一种比较有趣的语言定义欧拉函数. 显然我们只需要求出所有军人ans1和政客ans2,然后用求得的M减去独立数和就是学者的独立数和了. 由于善良的出题人已经帮我们把M给质因分解了,因此我们假定当前已经得到了ans1和ans2,那么根据欧拉函数的定义,ans1'=ans1+ans2*(p-1),ans2'=ans2+ans1*(p-1),因为新加入的质因子会让

Super A^B mod C 快速幂+欧拉函数降幂

uper A^B mod C Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Description Given A,B,C, You should quickly calculate the result of A^B mod C. (1<=A,C<=1000000000,1<=B<=10^1000000). Input There are

1408: [Noi2002]Robot|快速幂|欧拉函数

真是一道神题,语文渣渣表示已经给题意描述跪烂了.. 独立数显然就是欧拉函数φ 然后政客军人他们的分解成的奇素数的指数显然都是1,最初的思想就是暴力枚举只有1个奇函数的情况,2个,3个----这样显然是会超时,可以发现欧拉函数是满足积性的,所以可以放到一起乘起来算用一种类似于DP的"前缀和"的思想来做 ans1表示当前有奇数个奇数质因子的"前缀和" ans2表示当前有偶数个奇数质因子的"前缀和" 然后学者的独立数可以用总和减去前两个的和,因为欧拉函

hdu--4549--费马小定理&amp;快速幂&amp;欧拉函数

这题 蛮复杂的. 我自己做的时候 无法处理完 最后一步公式的转换 后来看到别人说这是 费马小定理 与 欧拉函数的思想下的转换 可是 我自己还推导不出来啊... 首先 你要发现f[n]=a^x * b^y其实指数x 与 y是fib数列中的f[n-1]与f[n]项( n>=1 并且数列是0 1 1 2 3 5 8 ...) 那么 其实题目就转换成了 f[n] = a^fib[n-1] * b^fib[n] % mod; 这边 不必要对于 a^fib[n-1]与 b^fib[n] 单独再在括号进行取模

【BZOJ 1409】 Password 数论(扩展欧拉+矩阵快速幂+快速幂)

读了一下题就会很愉快的发现,这个数列是关于p的幂次的斐波那契数列,很愉快,然后就很愉快的发现可以矩阵快速幂一波,然后再一看数据范围就......然后由于上帝与集合对我的正确启示,我就发现这个东西可以用欧拉函数降一下幂,因为两个数一定互质因此不用再加一个phi(m),于是放心的乘吧宝贝!! #include <cstdlib> #include <cstring> #include <cstdio> #include <iostream> #include &

矩阵快速幂递推+欧拉降幂

题意:给出F(1) = x , F(2) = y , a , b , 和递推关系F(n) = F(i-1)*F(i-2) * ab , 求F[N]. 解法:将F(n) 转化为f(1) . f(2) 和 ab 可以知道它们的幂都是裴波纳切数列,可以通过矩阵快速幂同时根据欧拉降幂递推幂时mod1e+6. 坑点:1.注意数据范围,先膜一波. 2.快速幂函数0 的0 次方输出1 , 不撸壮或则直接特判x,y,a == 0 时为0. #include <bits/stdc++.h> #define mo