poj 3734 矩阵快速幂+YY

题目原意:N个方块排成一列,每个方块可涂成红、蓝、绿、黄。问红方块和绿方块都是偶数的方案的个数。

sol:找规律列递推式+矩阵快速幂

设已经染完了i个方块将要染第i+1个方块。

a[i]=1-i方块中,红、绿方块数量都是偶数的方案数

b[i]=1-i方块中,红、绿方块数量一个是偶数一个是奇数的方案数(红even绿odd 或 红odd绿even)

c[i]=1-i方块中,红、绿方块数量都是奇数的方案数

可以得出递推公式:

a[i+1]=2*a[i]+b[i]    

b[i+1]=2*a[i]+2*b[i]+2*c[i]

c[i+1]=b[i]+2*c[i]

如何和矩阵结合起来呢?不妨把公式这样写一遍,

a[i+1]=2*a[i]+1*b[i]+0*c[i]    

b[i+1]=2*a[i]+2*b[i]+2*c[i]

c[i+1]=0*a[i]+1*b[i]+2*c[i]

然后可以YY出一个矩阵:

因此,

这样就可以用矩阵快速幂求解了。

 1 #include "iostream"
 2 #include "vector"
 3 #include "cstring"
 4 using namespace std;
 5
 6 typedef unsigned long int ULL;
 7 typedef vector<ULL> vec;
 8 typedef vector<vec> mat;
 9 const ULL P=10007;
10 int n,m;
11
12 mat mul(mat &A,mat &B)      //return A*B
13 {
14     mat C(A.size(),vec(B[0].size()));
15     for (int i=0;i<(int)A.size();i++)
16     {
17         for (int k=0;k<(int)B.size();k++)
18         {
19             for (int j=0;j<(int)B[0].size();j++)
20             {
21                 C[i][j]=(C[i][j]+A[i][k]*B[k][j])%P;
22             }
23         }
24     }
25     return C;
26 }
27
28 mat m_pow(mat A,int m)      //return A^m
29 {
30     mat B(A.size(),vec(A.size()));
31     for (int i=0;i<(int)A.size();i++)
32         B[i][i]=1;
33     while (m>0)
34     {
35         if (m&1)    B=mul(B,A);
36         A=mul(A,A);
37         m>>=1;
38     }
39     return B;
40 }
41
42 int main()
43 {
44     int T,N;
45     cin>>T;
46     while (T--)
47     {
48         cin>>N;
49         mat A(3,vec(3));
50         A[0][0]=2;  A[0][1]=1;  A[0][2]=0;
51         A[1][0]=2;  A[1][1]=2;  A[1][2]=2;
52         A[2][0]=0;  A[2][1]=1;  A[2][2]=2;
53
54         A=m_pow(A,N);
55
56         cout<<A[0][0]<<endl;
57     }
58     return 0;
59 }
60
61 /*
62 int main()
63 {
64     int T;
65     cin>>T;
66     while (T--)
67     {
68         cin>>n>>m;
69         mat A(n,vec(n));
70
71         for (int i=0;i<n;i++)
72             for (int j=0;j<n;j++)
73                 cin>>A[i][j];
74
75         A=m_pow(A,m);
76
77         ULL ans=0;
78         for (int i=0;i<n;i++)
79         {
80             ans+=A[i][i];
81             ans=ans%P;
82         }
83         cout<<ans<<endl;
84     }
85     return 0;
86 }
87 */

时间: 2024-10-31 18:53:57

poj 3734 矩阵快速幂+YY的相关文章

poj 3233 矩阵快速幂+YY

题意:给你矩阵A,求S=A+A^1+A^2+...+A^n sol:直接把每一项解出来显然是不行的,也没必要. 我们可以YY一个矩阵: 其中1表示单位矩阵 然后容易得到: 可以看出这个分块矩阵的左下角那块就可以得到要求的解S 我们取这一块,再减去一个单位矩阵1即可. 1 #include "iostream" 2 #include "vector" 3 #include "cstring" 4 #include "cstdio"

POJ 3070-Fibonacci(矩阵快速幂求斐波那契数列)

Fibonacci Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Practice POJ 3070 Appoint description:  System Crawler  (2015-02-28) Description In the Fibonacci integer sequence, F0 = 0, F1 = 1, and Fn = Fn ? 1 +

poj 3233(矩阵快速幂)

题目链接:http://poj.org/problem?id=3233: 题意:给出一个公式求这个式子模m的解: 分析:本题就是给的矩阵,所以很显然是矩阵快速幂,但有一点,本题k的值非常大,所以要用二分求和来减少运行时间. 代码: #include <set> #include <map> #include <stack> #include <queue> #include <math.h> #include <vector> #in

POJ 3070 矩阵快速幂解决fib问题

矩阵快速幂:http://www.cnblogs.com/atmacmer/p/5184736.html 题目链接 #include<iostream> #include<cstdio> using namespace std; typedef long long ll; #define MOD 10000 ll a[7],b[7],a0[7],b0[7]; void pow_mod(ll n) { a0[1]=a0[2]=a0[3]=1,a0[4]=0; b0[1]=b0[4]=

Fibonacci (poj 3070 矩阵快速幂)

Language: Default Fibonacci Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 10099   Accepted: 7211 Description In the Fibonacci integer sequence, F0 = 0, F1 = 1, and Fn = Fn ? 1 + Fn ? 2 for n ≥ 2. For example, the first ten terms of the

POJ 3070 矩阵快速幂

裸题,最简单fib的应用模板,算是新技能get 吧. 其实和快速幂差不多了,只是矩阵代替的递推式. 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 const int maxn = 1005; 6 struct node 7 { 8 int a[2][2]; 9 void init() 10 { 11 a[0][0] = a[1][0] =

Poj 3233 矩阵快速幂,暑假训练专题中的某一道题目,矩阵快速幂的模板

题目链接  请猛戳~ Description Given a n × n matrix A and a positive integer k, find the sum S = A + A2 + A3 + - + Ak. Input The input contains exactly one test case. The first line of input contains three positive integers n (n ≤ 30), k (k ≤ 109) and m (m <

poj 3070 矩阵快速幂简单题

基本运用,基本是模板题. 求fi[n].       (1,1)    *( 1  ) ( 1,0)     (  0) #include<iostream> #include<cstring> using namespace std; struct juz { int bat[3][3]; int x,y; //行 列 }; juz mutp(juz a,juz b) { juz c; c.x=a.x;c.y=b.y; memset(c.bat,0,sizeof(c.bat));

poj 3070 矩阵快速幂模板

题意:求fibonacci数列第n项 1 #include "iostream" 2 #include "vector" 3 #include "cstring" 4 using namespace std; 5 6 typedef unsigned long int ULL; 7 typedef vector<ULL> vec; 8 typedef vector<vec> mat; 9 const ULL P=10000