因为告诉你的是最大值v,说明那个矩阵里面肯定要有一个数=v,这样子很不好做,我们考虑容斥,转换为每个矩阵的数都<=v,通过2^n枚举每个最大值要不要-1(用来容斥)
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <ctime>
#include <iostream>
using namespace std;
const int mod = 1e9+7;
int fast_pow(int a, int x) {
int res = 1;
for(; x; x >>= 1) {
if(x&1) res = 1ll*res*a%mod;
a = 1ll*a*a%mod;
}
return res;
}
int h, w, m, n;
struct info {
int x1, y1, x2, y2, v;
} a[15], t[15], beg;
int siz(info x) { return (x.x2-x.x1+1)*(x.y2-x.y1+1); }
bool check(info x) { return x.x1 <= x.x2 && x.y1 <= x.y2 && x.v > 0; }
info add(info a, info b) {
int x1 = max(a.x1, b.x1);
int x2 = min(a.x2, b.x2);
int y1 = max(a.y1, b.y1);
int y2 = min(a.y2, b.y2);
int v = min(a.v, b.v);
return (info) {x1, y1, x2, y2, v};
}
int g[1<<15], f[1<<15];
void dfs1(int dep, info now, int s) {
if(!check(now)) return;
if(dep > n) { g[s] = siz(now); return; }
dfs1(dep+1, now, s<<1);
dfs1(dep+1, add(now, a[dep]), s<<1|1);
}
#define cnt __builtin_popcount
void getf() {
dfs1(1, beg, 0);
for(int s1 = 0; s1 < (1<<n); ++s1)
for(int s2 = 0; s2 <= s1; ++s2)
if((s1&s2) == s2) {
if(cnt(s1^s2)&1) f[s2] -= g[s1];
else f[s2] += g[s1];
}
}
int dfs2(int dep, int v, int s) {
if(!v) return 0;
if(dep > n)
return fast_pow(v, f[s]);
int res1 = dfs2(dep+1, v, s<<1);
int res2 = dfs2(dep+1, min(v, t[dep].v), s<<1|1);
return 1ll*res1*res2%mod;
}
int ans;
void dfs3(int dep, int k) {
if(dep > n) {
if(k) {
int res = dfs2(1, m, 0);// printf("res = %d\n", res);
ans += res, ans >= mod ? ans -= mod : 1;
}
else {
int res = dfs2(1, m, 0);// printf("res = %d\n", -res);
ans -= res, ans < 0 ? ans += mod : 1;
}
return;
}
t[dep] = a[dep]; dfs3(dep+1, k);
t[dep] = a[dep]; t[dep].v--; dfs3(dep+1, k^1);
}
void work() {
scanf("%d%d%d%d", &h, &w, &m, &n);
memset(f, 0, sizeof f);
memset(g, 0, sizeof g);
beg.x1 = beg.y1 = 1, beg.x2 = h, beg.y2 = w, beg.v = w;
for(int i = 1; i <= n; i++)
scanf("%d%d%d%d%d", &a[i].x1, &a[i].y1, &a[i].x2, &a[i].y2, &a[i].v);
getf(); ans = 0;
//printf("%d\n", g[1]);
dfs3(1, 1);
printf("%d\n", ans);
}
int main() {
int test;
scanf("%d", &test);
while(test--) work();
return 0;
}