【矩阵快速幂】ZOJ 3690 Choosing number
2015-07-11 18:54
309 查看
矩阵快速幂。。。顾名思义就是利用矩阵的结合律来进行快速幂运算。。。嘛,笔者也是做这道题两小时前把矩阵快速幂搞明白了的。。。所以其实还不熟= =
题目地址:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3690
首先我们的思路是建立矩阵的转换式,由题意可知在n个数中只有大于k的数字才能相邻,那么其实就是大于k的数字可以随便放啦。
所以令当前选择的数字大于k的部分为a,小于k的部分为b;则有:
| m-k m-k | | An | | An+1 |
| k k-1 | * | An+1 | = | An+2 | (原谅我不会画矩阵。。。)
然后就是这样,代码如下
题目地址:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3690
首先我们的思路是建立矩阵的转换式,由题意可知在n个数中只有大于k的数字才能相邻,那么其实就是大于k的数字可以随便放啦。
所以令当前选择的数字大于k的部分为a,小于k的部分为b;则有:
| m-k m-k | | An | | An+1 |
| k k-1 | * | An+1 | = | An+2 | (原谅我不会画矩阵。。。)
然后就是这样,代码如下
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #define LL long long using namespace std; struct mat { LL a,b; LL c,d; }ans,w; LL n,m,k; const int mod=1000000007; mat mix(mat a,mat b) { mat ans; ans.a=(a.a*b.a+a.b*b.c)%mod; ans.b=(a.a*b.b+a.b*b.d)%mod; ans.c=(a.c*b.a+a.d*b.c)%mod; ans.d=(a.c*b.b+a.d*b.d)%mod; return ans; } int main() { while(~scanf("%lld%lld%lld",&n,&m,&k)) { w.a=w.b=m-k; w.c=k; w.d=k-1; ans.a=ans.d=1; ans.b=ans.c=0; n--; while(n) { if(n&1) ans=mix(w,ans); w=mix(w,w); n=n>>1; //cout<<ans.a<<" "<<ans.b<<endl; //cout<<ans.c<<" "<<ans.d<<endl<<endl; } printf("%lld\n",((ans.a+ans.c)*(m-k)%mod+(ans.b+ans.d)*k%mod)%mod); } return 0; }
相关文章推荐
- 如何在android studio中导入外部包
- Xmanager注册吗
- Android 混淆代码汇总
- 星际之门(一)(凯莱定理+快速幂)
- DOM知识点归纳一
- What is the difference between static and global variables ?
- html中frameset的详细使用方法
- lightoj 1197 奇怪筛法
- SQLServer学习笔记系列11
- 谷歌宣布Android Studio将取代Eclipse
- 树莓派 常用命令
- 从CMD 连接db2 数据库
- NET中小型企业项目开发框架系列(一个)
- mongodb 创建用户
- BZOJ 1013 球形空间产生器sphere(高斯消元浮点型)
- 用C++实现最小公倍数和最大公约数
- mongodb 创建用户
- 信息系统项目管理案例分析(2)
- HashMap原理
- 3、fancyBox-master展示图片例子