codeforces#191_div2_C Magic Five 矩阵快速幂
来源:互联网 发布:怎么打开php文件 编辑:程序博客网 时间:2024/04/29 10:42
题目地址:点这里
额,思考的方式还是在纸上,举几个简单的例子。找找规律。
首先,只有一个循环节的时候,就是sigma pow(2,p[i]) 其中p[i] 为s[p[i]] =='0'||'5';
然后有k个循环节的时候,找到了递推方程。f[n]=f[n-1]+2^(Length*(n-1))*T;
其中T是一个循环节对应的方法数。
f[n]可以理解为,仅使用前n个循环节对应的方法数,那么对最后一个循环节,要么不用(f[n-1] ) ,要么用,前面n-1 循环节,对应(n-1)*Length 这么多元素,都可以取或者不取。
于是就是一个等比数列求和。
但是不能再分母上取模。
所以设计了一个矩阵,使用矩阵快速幂来解决。
注意:凡是两个int相乘的地方就要取mod。
代码:
#include<iostream>using namespace std;typedef long long inta;const int mod=1000000007;int p[100005];inta quick_mod(inta a,int n){ inta ans=1; while(n>0) { if(n&1) { ans=(ans*a)%mod; } a=(a*a)%mod; n>>=1; } return ans;}struct Matrix { inta p[2][2]; Matrix() { for(int i=0;i<2;i++) for(int j=0;j<2;j++) p[i][j]=(i==j)?1:0; }};Matrix multi(Matrix A,Matrix B){ Matrix ans; for(int i=0;i<2;i++) for(int j=0;j<2;j++) { inta sum=0; for(int k=0;k<2;k++) { sum=(sum+(A.p[i][k]*B.p[k][j])%mod)%mod; } ans.p[i][j]=sum; } return ans;}Matrix quick_mod(Matrix A,int n){ Matrix ans; while(n) { if(n&1) { ans=multi(ans, A); } A=multi(A, A); n>>=1; } return ans;}int main(){ string s; cin>>s; inta L=s.length(); inta Base=quick_mod(2,L); int k; cin>>k; inta T=0; int c=0; for(int i=0;i<s.length();i++) { if(s[i]=='0'||s[i]=='5') p[c++]=i; } for(int i=0;i<c;i++) { T=(T+quick_mod(2, p[i]))%mod; } Matrix A; A.p[0][0]=1; A.p[0][1]=0; A.p[1][0]=1; A.p[1][1]=Base; A=quick_mod(A, k-1); inta TB=(T*Base)%mod; cout<<((T*A.p[0][0])%mod+(TB*A.p[1][0])%mod)%mod<<endl; }
其实本题的答案就是T*(2^0+2^(L)+2^(2L)+...+2^(k-1)L)
就是枚举最后一位出现在第几个循环节,然后前面的长度任取。
等比数列求和的类似于快速幂的写法
改了一下,简洁很多。
代码:
#include<iostream>using namespace std;typedef long long inta;const int mod=1000000007;int p[100005];inta quick_mod(inta a,int n){ inta ans=1; while(n>0) { if(n&1) { ans=(ans*a)%mod; } a=(a*a)%mod; n>>=1; } return ans;}inta calc(inta A,int n) // 等比数列求和{ if(n==0) return 1; if(n==1) return (1+A)%mod; if(n%2==0) { inta x=calc(A,n/2); inta d=quick_mod(A, n/2); return ((d*(x-1))%mod+x)%mod; } else { inta x=calc(A,(n-1)/2); inta d=quick_mod(A, (n+1)/2); return ((d*x)%mod+x)%mod; } }int main(){ string s; cin>>s; inta L=s.length(); inta Base=quick_mod(2,L); int k; cin>>k; inta T=0; int c=0; for(int i=0;i<s.length();i++) { if(s[i]=='0'||s[i]=='5') p[c++]=i; } for(int i=0;i<c;i++) { T=(T+quick_mod(2, p[i]))%mod; } cout<<(calc(Base,k-1)*T)%mod<<endl; return 0; }
0 0
- codeforces#191_div2_C Magic Five 矩阵快速幂
- codeforces #327C Magic Five 矩阵快速幂加费马小定理加逆元
- CodeForces 327 C.Magic Five(快速幂)
- Codeforces Round #191 (Div. 2) C. Magic Five 等比数列的快速幂
- codeforces Magic Five
- Magic Five CodeForces
- 【codeforces #327C】 Magic Five 矩阵高速幂加等比加逆元
- CodeForces 327C Magic Five 二分求和 或 矩阵求和
- CodeForces Round #191 (327C) - Magic Five 等比数列求和的快速幂取模
- codeforces-327C Magic Five(等比数列求和+快速幂+逆元)
- codeforces 327C Magic Five
- codeforces 327C. Magic Five
- Codeforces Round #191 (Div. 2) C magic five
- Codeforces Round #191 (Div. 2) C. Magic Five
- Codeforces Round #191 (Div. 2) C. Magic Five
- Codeforces Round #191 (Div. 2) C. Magic Five
- 【数论】codeforces 327C Magic five
- CodeForces 327C Magic Five 题解&代码
- emacs中怎样修改Major Mode的快捷键
- PL/SQL 面向对象oop编程
- 删除Oracle中的重复记录
- Add cells, rows, or columns to an Excel document
- android 组件长按弹出上下文菜单
- codeforces#191_div2_C Magic Five 矩阵快速幂
- OpenCV IplImage数据结构
- 判断一个数中是不是含有1、含有多少个1
- numpy 数组与类型
- 图的小结
- 如何将内核静态库编译连接到驱动程序中去
- 数据库事务隔离级别
- 排序使得数组负数在正数左边且按照原来的顺序
- http状态码大全