题目大意:
就是给你一个二维平面
{
(
x
,
y
)
∣
1
≤
x
≤
n
,
1
≤
y
≤
m
}
\{(x,y)|1\leq x\leq n,1\leq y \leq m\}
{(x,y)∣1≤x≤n,1≤y≤m},你现在有3种颜色,你可以给写平面的点涂上颜色,问你至少存在4个点
(
x
1
,
y
1
)
,
(
x
2
,
y
2
)
,
(
x
1
,
y
2
)
,
(
x
2
,
y
1
)
(x1,y1),(x2,y2),(x1,y2),(x2,y1)
(x1,y1),(x2,y2),(x1,y2),(x2,y1)使得
color(x1,y1)=color(x1,y2)&&color(x2,y1)=color(x2,y2)
\text{color(x1,y1)=color(x1,y2)\&\&color(x2,y1)=color(x2,y2)}
color(x1,y1)=color(x1,y2)&&color(x2,y1)=color(x2,y2)
or
\text{or}
or
color(x1,y1)=color(x2,y1)&&color(x1,y2)=color(x2,y2)
\text{color(x1,y1)=color(x2,y1)\&\&color(x1,y2)=color(x2,y2)}
color(x1,y1)=color(x2,y1)&&color(x1,y2)=color(x2,y2)
的涂色方法有多少种?
输出方案数
mod
(
1
e
9
+
7
)
\text{mod}(1e9+7)
mod(1e9+7)
解题思路:
首先颜色数这么少?
那么根据容斥原理两两组合最多就9种情况,就是如果
m
a
x
{
n
,
m
}
≥
9
max\{n,m\}\ge9
max{n,m}≥9那么随便涂肯定有解!!
那么就好办了:
对于
m
a
x
{
n
,
m
}
<
9
max\{n,m\}<9
max{n,m}<9我们可以直接爆搜打不合法矩阵的表。
打了表直接快速幂即可细节见代码:
注意坑点是:
n==1||m==1
\text{n==1||m==1}
n==1||m==1是没结果的
ACcode
#include <bits/stdc++.h>
#define mid ((l + r) >> 1)
#define Lson rt << 1, l , mid
#define Rson rt << 1|1, mid + 1, r
#define ms(a,al) memset(a,al,sizeof(a))
#define log2(a) log(a)/log(2)
#define lowbit(x) ((-x) & x)
#define IOS std::ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define INF 0x3f3f3f3f
#define LLF 0x3f3f3f3f3f3f3f3f
#define f first
#define s second
#define endl '\n'
using namespace std;
const int N = 2e6 + 10, mod = 1e9 + 7;
const int maxn = 500010;
const long double eps = 1e-5;
const int EPS = 500 * 500;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PII;
typedef pair<ll,ll> PLL;
typedef pair<double,double> PDD;
template<typename T> void read(T &x) {
x = 0;char ch = getchar();ll f = 1;
while(!isdigit(ch)){if(ch == '-')f*=-1;ch=getchar();}
while(isdigit(ch)){x = x*10+ch-48;ch=getchar();}x*=f;
}
template<typename T, typename... Args> void read(T &first, Args& ... args) {
read(first);
read(args...);
}
int mat[9][9] = {
{3,9,27,81,243,729,2187,6561,19683},
{9,66,390,1800,6120,13680,15120,0,0},
{27,390,3198,13176,27000,13680,15120,0,0},
{81,1800,13176,24336,4320,0,0,0,0},
{243,6120,27000,4320,4320,0,0,0,0},
{729,13680,13680,0,0,0,0,0,0},
{2187,15120,15120,0,0,0,0,0,0},
{6561,0,0,0,0,0,0,0,0},
{19683,0,0,0,0,0,0,0,0},
};
int col[15][15];
bool vis[15][15];
int limx, limy;
inline int dfs(int x, int y) { //打表代码
int ans = 0;
for(int i = 1; i <= 3; ++ i) {
col[x][y] = i;
bool flag = 1;
for(int j = x-1; j >= 1; -- j) {
for(int z = y-1; z >= 1 && flag; -- z) {
if(col[x][y] == col[j][y] && col[x][z] == col[j][z]) flag = 0;
if(col[x][y] == col[x][z] && col[j][y] == col[j][z]) flag = 0;
}
if(flag == 0) break;
}
if(flag) {
if(x==limx&&y==limy) {
ans ++;
}
else if(x==limx) ans += dfs(1,y+1);
else ans += dfs(x+1,y);
}
}
return ans;
}
inline ll qim(ll a, ll b) {
ll res = 1;
while(b) {
if(b & 1) res = res * a % mod;
b >>= 1;
a = a * a % mod;
}
return res;
}
int main() {
IOS;
// for(int i = 1; i <= 9; ++ i)
// for(int j = 1; j <= 9; ++ j) {
// ms(col,0);
// limx = i, limy = j;
// mat[i][j] = dfs(1,1);
// }
// for(int i = 1; i <= 9; ++ i) {
// cout << "{";
// for(int j = 1; j <= 9; ++ j) {
// cout << mat[i][j];
// if(j==9) cout << "},\n";
// else cout << ",";
// }
// }
int T;
cin >> T;
while(T--) {
int n, m;
cin >> n >> m;
if(n == 1 || m == 1) cout << "0\n";
else if(n <= 9 && m <= 9){
// 总的减去不合法的
cout << ((qim(3,n*m) - mat[n-1][m-1]) % mod + mod) % mod << endl;
} else cout << qim(3,n*m) % mod << endl;
}
return 0;
}