E. Product Oriented Recurrence(矩阵快速幂+欧拉降幂)
时间:2019-06-12
本文章向大家介绍E. Product Oriented Recurrence(矩阵快速幂+欧拉降幂),主要包括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项中f1的个数 + 第i项中f1的个数 + 第i项中f1的个数 + 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
- MYSQL INNODB表压缩
- 剑指offer——年龄排序问题
- Mysql Group Replication介绍
- 剑指offer——快速排序
- 架构高性能网站秘笈(四)——反向代理缓存
- 架构高性能网站秘笈(一)——了解衡量网站性能的指标
- MYSQL5.6&5.7编译安装
- 架构高性能网站秘笈(三)——浏览器缓存
- 剑指 offer代码解析——面试题39判断平衡二叉树(高效方法)
- 跟着柴毛毛学Spring(4)——面向切面编程![这里写图片描述](http://img.blog.csdn.net/20171031111402095)
- MYSQL数据闪回方式
- 剑指 offer代码解析——面试题39判断平衡二叉树
- 跟着柴毛毛学Spring(3)——简化Bean的配置
- 剑指 offer代码解析——面试题39二叉树的深度
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Android编程实现自定义渐变颜色效果详解
- ES11屡试不爽的新特性,你用上了几个?
- Android设计模式之策略模式详解
- Android实现类似iOS风格的对话框实例代码
- Android 给图片加上水印的示例代码(支持logo+文字)
- Android studio 下JNI编程实例并生成so库的实现代码
- Android实现简单时钟View的方法
- Android编程之创建自己的内容提供器实现方法
- Android自定义View圆形和拖动圆、跟随手指拖动效果
- Android开发之OkHttpUtils的具体使用方法
- Xshell5连接虚拟机中的Linux的方法以及失败原因解决
- Android 多线程的实现方法总结
- Android编程之SQLite数据库操作方法详解
- 浅谈android组件化之ARouter简单使用
- Android ScrollView实现下拉弹回动画效果