离散化
状压DP,一不小心就T了.......
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int mod=1e9+7;
int h,w,m,n,Ex[1005],Ey[1005],Lim[1005],F[2005],cntx,cnty,cnt,Num[1005],belong[2005];
struct node{
int x1,y1,x2,y2,lim;
}a[15];
int pow(int a,int b){
int ans=1;
while (b){
if (b&1) ans=1ll*ans*a%mod;
a=1ll*a*a%mod;
b=b>>1;
}
return ans;
}
void Pre(){
sort(Ex+1,Ex+cntx+1); cntx=unique(Ex+1,Ex+cntx+1)-Ex-1;
sort(Ey+1,Ey+cnty+1); cnty=unique(Ey+1,Ey+cnty+1)-Ey-1;
cnt=0;
for (int i=2; i<=cntx; i++)
for (int j=2; j<=cnty; j++){
Num[++cnt]=(Ex[i]-Ex[i-1])*(Ey[j]-Ey[j-1]);
Lim[cnt]=m;
belong[cnt]=0;
for (int k=0; k<n; k++)
if (a[k].x1<=Ex[i-1] && a[k].x2>=Ex[i] && a[k].y1<=Ey[j-1] && a[k].y2>=Ey[j]) Lim[cnt]=min(Lim[cnt],a[k].lim);
for (int k=0; k<n; k++)
if (a[k].x1<=Ex[i-1] && a[k].x2>=Ex[i] && a[k].y1<=Ey[j-1] && a[k].y2>=Ey[j] && Lim[cnt]==a[k].lim) belong[cnt]|=(1<<k);
}
}
int main(){
int T;
scanf("%d",&T);
while (T--){
scanf("%d%d%d%d",&h,&w,&m,&n);
cntx=cnty=0;
Ex[++cntx]=0;
Ex[++cntx]=h;
Ey[++cnty]=0;
Ey[++cnty]=w;
for (int i=0; i<n; i++){
scanf("%d%d%d%d%d",&a[i].x1,&a[i].y1,&a[i].x2,&a[i].y2,&a[i].lim);
a[i].x1--,a[i].y1--;
Ex[++cntx]=a[i].x1;
Ex[++cntx]=a[i].x2;
Ey[++cnty]=a[i].y1;
Ey[++cnty]=a[i].y2;
}
Pre();
memset(F,0,sizeof(F));
F[0]=1;
for (int i=1; i<=cnt; i++)
for (int now=(1<<n)-1; now>=0; now--)
if (F[now]){
int Val=F[now];
F[now]=0;
(F[now|belong[i]]+=1ll*Val*(pow(Lim[i],Num[i])-pow(Lim[i]-1,Num[i])+mod)%mod)%=mod;
(F[now]+=1ll*Val*pow(Lim[i]-1,Num[i])%mod)%=mod;
}
printf("%d
",F[(1<<n)-1]);
}
return 0;
}