先转化成了离散网格图,然后状态dp即可....
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
#define mp(x, y) make_pair(x, y)
const int maxn = 100;
const int mod = 1e9+7;
struct line
{
int x1, y1, x2, y2, v;
line() {}
line(int x1, int y1, int x2, int y2, int v) : x1(x1), y1(y1), x2(x2), y2(y2), v(v) {}
}l[maxn];
LL dp[2][1 << 10];
int x[maxn];
int y[maxn];
int xlen[maxn];
int ylen[maxn];
int g[maxn][maxn];
int a[maxn][maxn];
int val[maxn][maxn];
LL w1[maxn][maxn];
LL w2[maxn][maxn];
vector<pair<int, int> > vec;
int N, n, m;
int solve(int xx, int yy, int pos1, int pos2)
{
vec.clear();
for(int i = 1; i <= N; i++) {
if(xx >= l[i].x1 && xx <= l[i].x2 && yy >= l[i].y1 && yy <= l[i].y2) {
vec.push_back(mp(l[i].v, i));
}
}
sort(vec.begin(), vec.end());
int t = 0;
for(int i = 0; i < vec.size(); i++) {
t |= 1 << vec[i].second - 1;
val[pos1][pos2] = min(val[pos1][pos2], l[vec[i].second].v);
if(i + 1 < vec.size() && vec[i+1].first != vec[i].first) break;
}
return t;
}
LL powmod(LL a, LL b)
{
LL res = 1, base = a;
while(b) {
if(b % 2) res = res * base % mod;
base = base * base % mod;
b /= 2;
}
return res;
}
void add(LL &x, LL y)
{
x += y;
x %= mod;
}
void DP()
{
memset(dp, 0, sizeof dp);
add(dp[0][0], powmod(val[1][1] - 1, g[1][1]));
add(dp[0][a[1][1]], powmod(val[1][1], g[1][1]) - powmod(val[1][1] - 1, g[1][1]));
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++) {
w1[i][j] = powmod(val[i][j]-1, g[i][j]);
w2[i][j] = (powmod(val[i][j], g[i][j]) - powmod(val[i][j]-1, g[i][j])) % mod;
}
int now = 0, pre = 1;
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= m; j++) {
if(i == 1 && j == 1) continue;
swap(now, pre);
memset(dp[now], 0, sizeof dp[now]);
for(int k = 0; k < 1 << N; k++) {
add(dp[now][k], dp[pre][k]*w1[i][j]%mod);
add(dp[now][k|a[i][j]], dp[pre][k]*w2[i][j]%mod);
}
}
}
LL ans = dp[now][(1 << N) - 1];
printf("%lld\n", (ans % mod + mod) % mod);
}
void work()
{
int cnt1 = 0, cnt2 = 0;
int x1, y1, x2, y2, v, M, h, w;
scanf("%d%d%d%d", &h, &w, &M, &N);
x[cnt1++] = 0;
x[cnt1++] = 2 * h + 1;
y[cnt2++] = 0;
y[cnt2++] = 2 * w + 1;
for(int i = 1; i <= N; i++) {
scanf("%d%d%d%d%d", &x1, &y1, &x2, &y2, &v);
l[i] = line(x1, y1, x2, y2, v);
x1 <<= 1, x2 <<= 1, y1 <<= 1, y2 <<= 1;
x1--, y1--;
x2++, y2++;
x[cnt1++] = x1;
x[cnt1++] = x2;
y[cnt2++] = y1;
y[cnt2++] = y2;
}
sort(x, x+cnt1);
sort(y, y+cnt2);
cnt1 = unique(x, x+cnt1) - x;
cnt2 = unique(y, y+cnt2) - y;
for(int i = 1; i < cnt1; i++) xlen[i] = x[i] - x[i-1];
for(int i = 1; i < cnt2; i++) ylen[i] = y[i] - y[i-1];
n = cnt1-1;
m = cnt2-1;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
val[i][j] = M;
int xx = 1, yy = 1;
for(int i = 1; i <= n; i++) {
yy = 1;
for(int j = 1; j <= m; j++) {
g[i][j] = (xlen[i] / 2) * (ylen[j] / 2);
a[i][j] = solve(xx, yy, i, j);
yy += ylen[j] / 2;
}
xx += xlen[i] / 2;
}
DP();
}
int main()
{
//freopen("data", "r", stdin);
int _;
scanf("%d", &_);
for(int i = 1; i <= _; i++) {
printf("Case #%d: ", i);
work();
}
return 0;
}