BZOJ 5010: [Fjoi2017]矩阵填数

离散化

状压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\n",F[(1<<n)-1]);
	}
	return 0;
}

  

猜你喜欢

转载自www.cnblogs.com/silenty/p/9887909.html