cf#747 E1. Rubik's Cube Coloring (easy version)

题目大意:

有一颗满二叉树,每一个节点可以涂一种颜色, 相邻两个节点不能涂同一种也不能涂魔方中对面的颜色。给定层数x,问有多少种涂色方式。

cf#747 E1. Rubik

思路:

从根节点开始往下, 根可以涂6中颜色, 子节点可以涂4种 ,因为“孙子”节点和根不相邻,所以“孙子”节点也是可以涂四种颜色。具体举个例子如下图:

cf#747 E1. Rubik

那么这题就很清晰了,除根节点外所有节点都是4种,只要求出有多少节点就行。因为是满二叉树,节点数量是二的层数次方减一。那最终答案就是:
cf#747 E1. Rubik

所以我给出了我的代码:

void solve(){
	cin >> x ;//开的全是ll
	cout<<(quick_pow(4 , quick_pow(2 , x , mod) - 2 , mod) * 6 ) % mod ; 
 
}

但是居然wa了,正解如下:

void solve(){
	cin >> x ;
	cout<<(quick_pow(4 , (1LL << x) - 2 , mod) * 6 ) % mod ; 
}

有一个小细节,在算2**x时,不能用快速幂,因为题中给的mod是1e9+7,快速幂会将2**x的值变小(回到1e9+7内)。正解是在ll里去用位移来算二的次方。

最后给一个快速幂板子:

inline ll quick_pow(ll a, ll k, ll p) {
	ll res = 1;//快速幂
	a %= p;
	while (k) {
		if (k & 1) res = res * a % p;
		a = a * a % p;
		k >>= 1;
	}
	return res % p ;
}