CodeForces 327C Magic Five 二分求和 或 矩阵求和
2014-04-09 23:38
363 查看
这是个快速幂的题吧,,刚开始交的时候一直wa在第5组测试数据,,表示1000000007这个东西,一定要找个时间练练1000000007相关的题 T_T
题目大意:
给你一串数字, 然后给出一个数字k,表示有k次重复,从这个数字串中去掉一些数(也可以不去掉任何数)要求剩下的数能被5整除,剩下的数可以有前导零,不同的去除方法即使得到相同的数字串也算不同的方法。 求可能的方法的数量,结果模上1000000007。
大致思路:
首先考虑不进行k次重复时,这个数字串要使得结尾是0或5,那么,在被作为最后以为的0或5之前的数可以去掉或者不去掉,在其之后的数必须都去掉。
那么,以一个数字串的第 i 位作为结尾的可能性就有 2 ^ i 种, 由于数字串重复,记字符串未重复时长度为 n, 那么数字串的第 i + n, i+ 2*n, i + 3*n ,,,,,, i + (k - 1)*n都可以作为结尾。
对于原数字串,第 i 位作为结尾, i + n, i + 2*n, i + 3*n, i + 4*n,,,,i + k*n 的可能方式有 (2 ^ i ) * (2^0 + 2^n + 2^(2*n) + 2^(3*n) + ....+ 2^((k - 1)*n);
对于原数字串统计它的 2 ^ i 的总和就可以了。
这里给出两种做法
解法一:
将 (2^0 + 2^n + 2^(2*n) + 2^(3*n) + ....+ 2^((k - 1)*n) 每次二分变为:
((2^0 + 2^n + 2^(2*n) + 2^(3*n) + ....+ 2^((k - 1)/2)*n)) * (1 + 2 ^ ((((k - 1)/2) + 1)*n))
对于每个2的次方都用快速幂,代码如下:
Result : Accepted Memory : 300 KB Time : 62 ms
解法二:
采用矩阵求等比数列的和
这个还是看经验问题吧,,,
Result : Accepted Memory : 300 KB Time : 62ms
好了,就写到这里吧,,
刚才一个很好的高中同学有些情绪低落,中途去安慰了一下,讨论了一下人生观,希望她能挺过这些困难,走向灿烂的阳光~
题目大意:
给你一串数字, 然后给出一个数字k,表示有k次重复,从这个数字串中去掉一些数(也可以不去掉任何数)要求剩下的数能被5整除,剩下的数可以有前导零,不同的去除方法即使得到相同的数字串也算不同的方法。 求可能的方法的数量,结果模上1000000007。
大致思路:
首先考虑不进行k次重复时,这个数字串要使得结尾是0或5,那么,在被作为最后以为的0或5之前的数可以去掉或者不去掉,在其之后的数必须都去掉。
那么,以一个数字串的第 i 位作为结尾的可能性就有 2 ^ i 种, 由于数字串重复,记字符串未重复时长度为 n, 那么数字串的第 i + n, i+ 2*n, i + 3*n ,,,,,, i + (k - 1)*n都可以作为结尾。
对于原数字串,第 i 位作为结尾, i + n, i + 2*n, i + 3*n, i + 4*n,,,,i + k*n 的可能方式有 (2 ^ i ) * (2^0 + 2^n + 2^(2*n) + 2^(3*n) + ....+ 2^((k - 1)*n);
对于原数字串统计它的 2 ^ i 的总和就可以了。
这里给出两种做法
解法一:
将 (2^0 + 2^n + 2^(2*n) + 2^(3*n) + ....+ 2^((k - 1)*n) 每次二分变为:
((2^0 + 2^n + 2^(2*n) + 2^(3*n) + ....+ 2^((k - 1)/2)*n)) * (1 + 2 ^ ((((k - 1)/2) + 1)*n))
对于每个2的次方都用快速幂,代码如下:
Result : Accepted Memory : 300 KB Time : 62 ms
/* * Author : Gatevin * Time : 2014.4.9 22:07 * Problem : CodeForces 327C Magic Five * Tag : quick_pow, math, geometric sequence */ #include<cstdio> #include<iostream> #include<algorithm> #include<cstring> typedef long long lint; using namespace std; const int mod = 1000000007; string s; int times; lint quick_pow(lint base, lint pow)//快速幂 { lint rep = 1; while(pow) { if(pow & 1) { rep = (rep * base)%mod; } pow >>= 1; base = (base*base)%mod; } return rep; } lint two_divide(lint base, lint len)//对于要求和的式子每次二分,左右两边有一个倍数关系,有可能多一项 { if(len == 1) return 1; lint tmp = two_divide(base, len >> 1); lint rep = ((1 + quick_pow(base, len >> 1))*tmp)%mod; if(len & 1)//多一项时 { rep = (rep + quick_pow(base, len - 1))%mod; } return rep; } int main() { cin>>s>>times; lint ans = 0; for(int i = 0; i <= s.size() - 1; i++) { if(s[i] == '0' || s[i] == '5') { ans = ( ans + quick_pow(2,i))%mod;//式子的一部分 } } ans = (ans*two_divide(quick_pow(2,s.size()), times))%mod;//乘上另一部分 cout<<ans<<endl; return 0; }
解法二:
采用矩阵求等比数列的和
这个还是看经验问题吧,,,
Result : Accepted Memory : 300 KB Time : 62ms
/* * Author : Gatevin * Time : 2014.4.9 23:36 * Problem : CodeForces 327C Magic Five * Tag : Matrix, math, geometric progression */ #include<cstdio> #include<cstring> #include<algorithm> #include<iostream> using namespace std; typedef long long lint; const lint mod = 1000000007; struct Matrix { lint 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 Mutiple(Matrix A, Matrix B) { Matrix C; for(int i = 0; i < 2; i++) { for(int j = 0; j < 2; j++) { C.p[i][j] = 0; for(int k = 0; k < 2; k++) { C.p[i][j] = (C.p[i][j] + A.p[i][k]*B.p[k][j]%mod)%mod; } } } return C; } Matrix quick_pow(Matrix A, lint pow)//矩阵快速幂 { Matrix I; while(pow) { if(pow & 1) { I = Mutiple(I, A); } pow >>= 1; A = Mutiple(A, A); } return I; } lint quick_pow(lint base, lint pow) { lint ret = 1; while(pow) { if(pow & 1) { ret = (ret * base)%mod; } pow >>= 1; base = (base* base)%mod; } return ret; } string s; lint times; int main() { cin>>s>>times; lint ans = 0; for(lint i = 0; i <= s.size() - 1; i++) { if(s[i] == '0' || s[i] == '5') { ans = (ans + quick_pow(2, i))%mod;//统计s中可以的可能数 } } lint base = quick_pow(2, s.size()); Matrix I; I.p[0][0] = 1; I.p[0][1] = 0; I.p[1][0] = 1; I.p[1][1] = base; I = quick_pow(I, times); cout<<(ans*I.p[1][0])%mod<<endl; return 0; }
好了,就写到这里吧,,
刚才一个很好的高中同学有些情绪低落,中途去安慰了一下,讨论了一下人生观,希望她能挺过这些困难,走向灿烂的阳光~
相关文章推荐
- CodeForces 448D Multiplication Table(二分,CodeForces,矩阵中找数字)
- hdu 2254 奥运(矩阵降幂+二分求和)
- POJ 3233 Matrix Power Series (矩阵快速幂+等比数列二分求和)
- poj3233 矩阵等比数列求和 二分
- HDU 1588 Gauss Fibonacci(矩阵快速幂+二分等比序列求和)
- POJ 3233 矩阵运算,等比数列二分求和,矩阵
- codeforces 700A As Fast As Possible 二分求和?我觉得直接解更好
- HDU 1588 二分矩阵连乘求和
- HDU 2254 奥运(矩阵快速幂+二分等比序列求和)
- hdu 1588 Gauss Fibonacci(等比矩阵二分求和)
- Codeforces 327C 乘法逆元 + 费马小定理 || 等比数列二分求和取模
- SPOJ AMR10E Stocks Prediction --二分求和+矩阵快速幂
- [ACM] POJ 3233 Matrix Power Series (求矩阵A+A^2+A^3...+A^k,二分求和或者矩阵转化)
- HDU1588-Gauss Fibonacci(矩阵快速幂+等比数列二分求和)
- [ACM] POJ 3233 Matrix Power Series (求矩阵A+A^2+A^3...+A^k,二分求和或者矩阵转化)
- poj 3233Matrix Power Series(矩阵快速幂 二分求和 求累乘的和)
- HDU 1588 Gauss Fibonacci(矩阵高速幂+二分等比序列求和)
- Present - CODEFORCES, 460c 二分 扫描线求和
- HDU1588-Gauss Fibonacci(矩阵高速幂+等比数列二分求和)
- POJ - 3233 Matrix Power Series (矩阵等比二分求和)