Blocks POJ - 3734(白书例题)

题目大意:

给定N个方块排成一列。先用红、蓝、绿、黄四种颜色涂方块,问红色方块跟绿色方块同为偶数的方案有多少个

分析:

    设涂到第i个方块时,红绿都是偶数的方案数为ai,两者中只有一者为偶数bi,两者都是奇数的方案ci,可以得
到下列递推:
(先说a[i+1]的递推):
1.到i都为偶数,i+1个都涂另外两种颜色中的一个(所以就是a[i]×2)
2.到i只有一个为奇数,i+1涂成奇数的那个(所以时b[i])
综上所述:a[i+1]=b[i]+a[i]×2
同理b[i+1]=2×a[i]+2×b[i]+2×c[i]
     c[i+1]=b[i]+2×c[i]
/*
a[i] 	|2 1 0|^n  a[0](1)
b[i]  = |2 2 2|     b[0](0)
c[i]	|0 1 2|      c[0](0)
*/

code:

#define debug
#include<stdio.h>
#include<math.h>
#include<cmath>
#include<queue>
#include<stack>
#include<string>
#include<cstring>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<vector>
#include<functional>
#include<iomanip>
#include<map>
#include<set>
#define pb push_back
#define dbg(x) cout<<#x<<" = "<<(x)<<endl;
#define lson l,m,rt<<1
#define cmm(x) cout<<"("<<(x)<<")";
#define rson m+1,r,rt<<1|1
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll>PLL;
typedef pair<int,ll>Pil;
typedef pair<ll,int>Pli;
const ll INF = 0x3f3f3f3f;
const ll inf=0x7fffffff;
const double eps=1e-8;
const int maxn =1000000;
const int N = 510;
const ll mod=1e9+7;
const ll MOD=10007;
//------
//define
typedef vector<int> vec;
typedef vector<vec> mat;

mat mul(mat &A,mat&B){
	mat C(A.size(),vec(B[0].size()));
	for(int i=0;i<A.size();i++){
		for(int k=0;k<B.size();k++){
			for(int j=0;j<B[0].size();j++){
				C[i][j]=(C[i][j]+A[i][k]*B[k][j])%MOD;
			}
		}
	}
	return C;
}
mat pow(mat A,ll n){
	mat B(A.size(),vec(A.size()));
	//单位阵 I
	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;
}
//solve
void solve() {
	int T;
	cin>>T;
	while(T--){
		int N;
		cin>>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);
		cout<<A[0][0]<<endl;
	}
}
int main() {
	ios_base::sync_with_stdio(false);
#ifdef debug
	freopen("in.txt", "r", stdin);
//	freopen("out.txt","w",stdout);
#endif
	cin.tie(0);
	cout.tie(0);
	solve();
	/*
		#ifdef debug
			fclose(stdin);
			fclose(stdout);
			system("out.txt");
		#endif
	*/
	return 0;
}

原文地址:https://www.cnblogs.com/visualVK/p/9119331.html

时间: 2024-10-31 03:55:08

Blocks POJ - 3734(白书例题)的相关文章

la3523 白书例题 圆桌骑士 双联通分量+二分图

具体题解看大白书P316 #include <iostream> #include <algorithm> #include <vector> #include <string.h> #include <stack> #include <cstdio> using namespace std; struct Edge{int u,v;}; const int maxn = 1000+10; int pre[maxn],iscut[ma

POJ 3734 Blocks

                                                         POJ 3734   Blocks Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Description Panda has received an assignment of painting a line of blocks. Since Panda is such an

[POJ 3734] Blocks (矩阵快速幂、组合数学)

Blocks Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 3997   Accepted: 1775 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 paint

6.12白书第五章图论总结——司雨寒

之前我的图论一直都是DFS一下,BFS一下,求个欧拉回路,拓扑排个序这种渣渣水平. 终于鼓起勇气拾起白书第五章的东西. 学(bei)习(song)了一下求双连通分量,二分图的判定,强连通分量,2-SAT. DFS加上时间戳这个东西,很强大. 最后刷了白书上的例题: BCC: LA3523 可以参加会议的是双联通分量上的奇圈 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include

黑书例题 Fight Club 区间DP

题目可以在bnuoj.soj等OJ上找到. 题意: 不超过40个人站成一圈,只能和两边的人对战.给出任意两人对战的输赢,对于每一个人,输出是否可能是最后的胜者. 分析: 首先序列扩展成2倍,破环成链. dp[i][j]表示i和j能够相遇对打,那么dp[i][i+n]为真代表可以成为最后胜者. 枚举中间的k,若i和j都能和k相遇,且i和j至少一人能打赢k,那么i和j可以相遇. 复杂度o(n^3) 1 #include<cstdio> 2 #include<cstring> 3 usi

Uva10474-STL水题-白书

白书的一道水题.话说好久没认真做难题了.今天出了排名,所有队伍里倒数第一啊! 代码没什么可说的了. #include <algorithm> #include <cstring> #include <ctype.h> #include <cstdlib> #include <cstdio> #include <vector> #include <string> #include <queue> #include

白书 5.4.3 果园的里的树

果园里的树排列成矩阵.他们的x和y的坐标均是1~99的整数.输入若干个三角形,依次统计每个三角形内部和边界上共有多少棵树. 输入: 1.5  1.5       1.5  6.8      6.8  1.5 10.7  6.9     8.5  1.5      14.5  1.5 此题用三角形有向面积来解,求有向面积2倍的函数为: double area(double x0,double y0,double x1,double y1,double x2,double,y2) { return

白书 5.4.4 多少块土地

此题初识欧拉公式 V - E + F = 2. 其中V是顶点(即所有线段的断点数加上交点数),E是边数(即n段椭圆弧加上这些线段被切成的段数),F是面数(即土地块数加上椭圆外那个无穷大的面). ------------------------------------------------------------------------------------------------------- 有一块椭圆的地,你可以在边界上选n个点,并两两连接得到n(n-1)/2条线段.它们最多能把土地分成

白书 第九章 例 9.24 复制书稿 题解

题目解法: 题解 白书 第九章 例 9.24 复制书稿 题解,码迷,mamicode.com