Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 4036 | Accepted: 1799 |
Description
Panda has received an assignment of painting a line of blocks. Since Panda is such an intelligent boy, he starts to think of a math problem of painting. Suppose there are N blocks in a line and each block can be paint red, blue, green or yellow. For some myterious reasons, Panda want both the number of red blocks and green blocks to be even numbers. Under such conditions, Panda wants to know the number of different ways to paint these blocks.
Input
The first line of the input contains an integer T(1≤T≤100), the number of test cases. Each of the next T lines contains an integer N(1≤N≤10^9) indicating the number of blocks.
Output
For each test cases, output the number of ways to paint the blocks in a single line. Since the answer may be quite large, you have to module it by 10007.
Sample Input
2 1 2
Sample Output
2 6
题意:
给出 T(1 ~ 100),代表有 T 个样例,后给出 N(1 ~ 10 ^ 9),代表有 N 个格子。给每个格子填色,可以填红蓝绿黄四种颜色,求染成红色和绿色同时为偶数的染色方案个数。结果模 10007。
思路:
矩阵快速幂。书上例题。设 ai 为同时为偶数的方法数,bi 为一个为偶数一个为奇数的方法数, ci 为同时为奇数的方法数,所以:
ai+1 = 2 x ai + bi ;
bi+1 = 2 x ai + 2 x bi + 2 x ci ;
ci+1 = bi + 2 x ci;
于是可以生成矩阵:
ai+1 2 1 0 ai ai 2 1 0 1
( bi+1 ) = ( 2 2 2 ) x ( bi ) -> ( bi ) = ( 2 2 2 ) ^ i X ( 0 )
ci+1 0 1 2 ci ci 0 1 2 0
最后得出来的矩阵中的 A [ 0 ] [ 0 ] 就是答案。
AC:
#include <cstdio> #include <cstring> #include <algorithm> #include <vector> using namespace std; typedef vector<int> vec; typedef vector<vec> mat; const int MOD = 10007; mat mul (mat a, mat b) { mat c(a.size(), vec(b[0].size())); for (int i = 0; i < a.size(); ++i) { for (int j = 0; j < b[0].size(); ++j) { for (int k = 0; k < b.size(); ++k) { c[i][j] = (c[i][j] + a[i][k] * b[k][j]) % MOD; } } } return c; } mat pow (mat a, int n) { mat b(a.size(), vec(a[0].size())); for (int i = 0; i < a.size(); ++i) { b[i][i] = 1; } while (n > 0) { if (n & 1) b = mul(b, a); a = mul(a, a); n >>= 1; } return b; } int main() { int t; scanf("%d", &t); while (t--) { int n; scanf("%d", &n); mat a(3, vec(3)); a[0][0] = 2, a[0][1] = 1, a[0][2] = 0; a[1][0] = 2, a[1][1] = 2, a[1][2] = 2; a[2][0] = 0, a[2][1] = 1, a[2][2] = 2; a = pow(a, n); printf("%d\n", a[0][0]); } return 0; }
相关推荐
快速生成特定类型的矩阵和向量,Eigen提供了便捷的方法: - `MatrixXd A = MatrixXd::Zero(m, n);` 生成全零矩阵。 - `MatrixXd A = MatrixXd::Ones(m, n);` 生成全一矩阵。 - `MatrixXd A = MatrixXd::Identity(m, ...
4. **Fibonacci序列**:实现快速计算斐波那契数列的算法,如矩阵快速幂等方法。 **开发和使用** 使用libNT库的开发者可以利用其提供的API接口,轻松地集成到自己的项目中。`CHANGELOG`文件记录了库的版本更新历史...
T4和T5则涵盖了图论、深度优先搜索、DP、计算几何、矩阵乘法、快速幂、最小生成树、差分约束和最短路径算法等多种算法。 总的来说,CSP备考需要考生具备扎实的算法基础,熟练掌握各种数据结构和算法,并能灵活运用...
书中提供的C/C++代码使得理论知识能够快速转化为实际应用。 #### 标签解读: - **标签**:“Algorithm” - 这个标签表明了本书的核心主题——算法,意味着读者可以从本书中学到各种类型的算法及其应用场景。 ###...
- **2.8 就地矩阵转置 (In-place matrix transposition)**:介绍了如何不使用额外内存进行矩阵转置。 - **2.9 通过三次反转实现旋转 (Rotation by triple reversal)**:提供了一种通过三次反转实现元素旋转的方法。 ...