HDU 4471 矩阵快速幂 Homework
2013-09-02 12:40
232 查看
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=4471
解题思路,矩阵快速幂····特殊点特殊处理·····
令h为计算某个数最多须知前h个数,于是写出方程:
D =
V[x] =
显然有V[x+1] = D*V[x].D是由系数行向量,一个(h-1)*(h-1)的单位矩阵,和一个(h-1)*1的0矩阵组成。V[x]是一个h行,1列的矩阵。
初始条件为V[m] = (f[m],f[m-1],`````).如果m>h,那么多余的部分不会用到,如果m<h剩下的部分用0取代,相当于人为的添加前项f[0] = 0,f[-1] = 0·····这不会影响结果,而且式子仍然成立。由此计算出V
,答案就为V[1][1].
其余看一下代码就OK了,还有别人的解题报告,也可以看一下:
链接:
http://www.07net01.com/program/547544.html
我的代码:
View Code
http://acm.hdu.edu.cn/showproblem.php?pid=4471
解题思路,矩阵快速幂····特殊点特殊处理·····
令h为计算某个数最多须知前h个数,于是写出方程:
D =
c1 | c2 | ``` | c[h-1] | c[h] |
1 | 0 | ``` | 0 | 0 |
0 | 1 | ``` | 0 | 0 |
0 | 0 | 0 | 0 | |
0 | 0 | 1 | 0 |
f[x] |
f[x-1] |
` |
` |
f[x-h+1] |
初始条件为V[m] = (f[m],f[m-1],`````).如果m>h,那么多余的部分不会用到,如果m<h剩下的部分用0取代,相当于人为的添加前项f[0] = 0,f[-1] = 0·····这不会影响结果,而且式子仍然成立。由此计算出V
,答案就为V[1][1].
其余看一下代码就OK了,还有别人的解题报告,也可以看一下:
链接:
http://www.07net01.com/program/547544.html
我的代码:
#include<cstdio> #include<algorithm> using namespace std; const int N =102; const int mod = 1000000007; int h;//计算f[x]时最多和前面h个数有关 struct matrix { int row,col; int m ; void init(int row,int col) { this->row = row; this->col = col; for(int i=0; i<=row; ++i) for(int j=0; j<=col; ++j) m[i][j] = 0; } } A,pm[33],ans; matrix operator*(const matrix & a,const matrix& b) { matrix res; res.init(a.row,b.col); for(int k=1; k<=a.col; ++k) { for(int i=1; i<= res.row; ++i) { if(a.m[i][k] == 0 ) continue; for(int j = 1; j<=res.col; ++j) { if(b.m[k][j] == 0 ) continue; res.m[i][j] = (1LL *a.m[i][k]*b.m[k][j] + res.m[i][j])%mod; } } } return res; } void cal(int x) { for(int i=0; i<=31; ++i) if(x & (1<<i) ) ans = pm[i]*ans; } void getPm() { pm[0] = A; for(int i=1; i<=31; ++i) pm[i] = pm[i-1]*pm[i-1]; } struct sp//特殊点 { int nk,tk;//nk为点的位置,tk为计算nk时和前面tk个数有关 int ck ; bool operator<(const sp & o)const//按照nk排序 { return nk<o.nk; } } p ; int main() { // freopen("in.txt","r",stdin); int n,m,q,t,f ,c ,kase=0; while(~scanf("%d%d%d",&n,&m,&q)) { for(int i=m; i>0; --i) scanf("%d",&f[i]); scanf("%d",&t); h =t; for(int i=1; i<=t; ++i) scanf("%d",&c[i]); for(int i=0; i<q; ++i) { scanf("%d%d",&p[i].nk,&p[i].tk); if(p[i].tk > h) h = p[i].tk; for(int j=1; j<=p[i].tk; ++j) scanf("%d",&p[i].ck[j]); } sort(p,p+q); A.init(h,h); for(int i=1; i<=t; ++i) A.m[1][i] = c[i]; for(int i=2; i<=h; ++i) A.m[i][i-1] = 1; getPm(); ans.init(h,1); for(int i = m; i > 0; --i) ans.m[i][1] = f[i]; int last=m; for(int i=0; i<q; ++i) { if( p[i].nk <=last || p[i].nk >n ) continue; cal( p[i].nk-last-1); last = p[i].nk; for(int j=1; j<=p[i].tk; ++j) A.m[1][j] = p[i].ck[j]; for(int j=p[i].tk+1; j<=h; ++j) A.m[1][j] = 0; ans =A*ans; } cal(n-last); printf("Case %d: %d\n",++kase,ans.m[1][1]); } return 0; }
View Code
相关文章推荐
- hdu-4471-Homework-矩阵快速幂+优化加速
- hdu-4471-Homework-矩阵快速幂+优化加速
- HDU-4471 Homework 矩阵运算上的优化
- hdu 2604 矩阵快速幂
- HDU 1575 Tr A(矩阵快速幂)
- hdu 4686(矩阵快速幂)
- HDU 2276 Kiki & Little Kiki 2(矩阵快速幂)
- 【HDU 1575】Tr A (矩阵快速幂)
- hdu 4565 So Easy! 矩阵快速幂
- HDU1575--Tr A(矩阵快速幂)
- HDU 1575-Tr A(矩阵快速幂)
- hdu 1005 Number Sequence(矩阵连乘+二分快速求幂)
- hdu 2604 Queuing(矩阵快速幂乘法)
- hdu 1005Number Sequence (矩阵快速幂)
- HDU 1757-A Simple Math Problem(矩阵快速幂)
- HDU 5895 矩阵快速幂+欧拉降幂公式+指数循环节
- HDU 1005 Number Sequence(基础矩阵快速幂)
- hdu 1757 A Simple Math Problem(矩阵快速幂)
- HDU 2157 How many ways??【矩阵快速幂】
- HDU 4549 M斐波那契数列(矩阵快速幂3)+费马小定理