状压 dp。参考there
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
typedef long long ll;
int T, h, w, m, n, dp[1055][1055], qx[55], qy[55], dx, dy, blc, sss[505], bel[505];
int maxn[505];
const int mod=1000000007;
struct Node{
int xu, yu, xv, yv, vv;
}nd[15];
bool f(int x, int y, int i){
return (x>nd[i].xu && y>nd[i].yu && x<=nd[i].xv && y<=nd[i].yv);
}
int ksm(int a, int b){
int re=1;
while(b){
if(b&1) re = (ll)re * a % mod;
a = (ll)a * a % mod;
b >>= 1;
}
return re;
}
int main(){
cin>>T;
while(T--){
memset(dp, 0, sizeof(dp));
memset(bel, 0, sizeof(bel));
dx = dy = blc = 0;
scanf("%d %d %d %d", &h, &w, &m, &n);
for(int i=1; i<=n; i++){
scanf("%d %d %d %d %d", &nd[i].xu, &nd[i].yu, &nd[i].xv, &nd[i].yv, &nd[i].vv);
nd[i].xu--; nd[i].yu--;
qx[++dx] = nd[i].xu; qx[++dx] = nd[i].xv;
qy[++dy] = nd[i].yu; qy[++dy] = nd[i].yv;
}
qx[++dx] = 0;
qy[++dy] = 0;
qx[++dx] = h;
qy[++dy] = w;
sort(qx+1, qx+1+dx);
sort(qy+1, qy+1+dy);
dx = unique(qx+1, qx+1+dx) - (qx + 1);
dy = unique(qy+1, qy+1+dy) - (qy + 1);
for(int i=2; i<=dx; i++)
for(int j=2; j<=dy; j++){
blc++;
sss[blc] = (qx[i] - qx[i-1]) * (qy[j] - qy[j-1]);
maxn[blc] = m;
for(int k=1; k<=n; k++)
if(f(qx[i], qy[j], k))
maxn[blc] = min(maxn[blc], nd[k].vv);
for(int k=1; k<=n; k++)
if(f(qx[i], qy[j], k) && maxn[blc]==nd[k].vv)
bel[blc] |= 1<<(k-1);
}
dp[0][0] = 1;
for(int i=1; i<=blc; i++){
int fai=ksm(maxn[i]-1, sss[i]);
int suc=(ksm(maxn[i], sss[i])-fai+mod)%mod;
for(int j=0; j<(1<<n); j++){
dp[i][j] = (dp[i][j] + (ll)dp[i-1][j]*fai%mod) % mod;
dp[i][j|bel[i]] = (dp[i][j|bel[i]] + (ll)dp[i-1][j]*suc%mod) % mod;
}
}
printf("%d
", dp[blc][(1<<n)-1]);
}
return 0;
}