记录编号 399375 评测结果 AAAAAAAAAA
题目名称 [HAOI 2017]方案数 最终得分 100
用户昵称 GravatarFoolMike 是否通过 通过
代码语言 C++ 运行时间 3.193 s
提交时间 2017-04-26 13:23:32 内存使用 5.83 MiB
显示代码纯文本
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=110,O=1e4+10,p=119<<23|1;
struct pt{ll x,y,z;}P[O];
ll n,m,r;int o,size;
bool OK(ll &s,ll &t){return (s&t)==s;}
bool cmp(const pt &a,const pt &b){
	if (a.x!=b.x) return a.x<b.x;
	if (a.y!=b.y) return a.y<b.y;
	return a.z<b.z;
}
int C[N][N],v[N][N][N];
int inc(int x,int y){x+=y;return x>=p?x-p:x;}
int dec(int x,int y){x-=y;return x<0?x+p:x;}
int mul(int x,int y){return (ll)x*y%p;}
void init(){
	for (int i=0;i<N;i++){
		C[i][0]=1;
		for (int j=1;j<=i;j++) C[i][j]=inc(C[i-1][j-1],C[i-1][j]);
	}
	v[0][0][0]=1;
	for (int i=0;i<=64;i++)
	for (int j=0;j<=64;j++)
	for (int k=0;k<=64;k++)
	for (int l=0;l<=64;l++){
		if (l>i) v[l][j][k]=inc(v[l][j][k],mul(v[i][j][k],C[l][i]));
		if (l>j) v[i][l][k]=inc(v[i][l][k],mul(v[i][j][k],C[l][j]));
		if (l>k) v[i][j][l]=inc(v[i][j][l],mul(v[i][j][k],C[l][k]));
	}
}
int cnt(ll x){
	int ans=0;
	for (;x;x-=x&-x) ans++;
	return ans;
}
int cx[O],cy[O],cz[O];
int DP[2][O],*x=DP[0],*y=DP[1];
int main()
{
	freopen("problema.in","r",stdin);
	freopen("problema.out","w",stdout);
	scanf("%lld%lld%lld",&n,&m,&r);
	scanf("%d",&o);
	for (int i=1;i<=o;i++){
		ll x,y,z;
		scanf("%lld%lld%lld",&x,&y,&z);
		if (OK(x,n)&&OK(y,m)&&OK(z,r)) P[++size]=(pt){x,y,z};
	}
	sort(P+1,P+size+1,cmp);
	for (int i=1;i<=size;i++){
		cx[i]=cnt(P[i].x);
		cy[i]=cnt(P[i].y);
		cz[i]=cnt(P[i].z);
	}
	init();
	cx[size+1]=cnt(n);
	cy[size+1]=cnt(m);
	cz[size+1]=cnt(r);
	for (int la=0;la<=size;la++)
		x[la]=v[cx[size+1]-cx[la]][cy[size+1]-cy[la]][cz[size+1]-cz[la]];
	for (int p=size;p;p--,swap(x,y))
	for (int la=0;la<p;la++){
		y[la]=x[la];
		if (OK(P[la].x,P[p].x)&&OK(P[la].y,P[p].y)&&OK(P[la].z,P[p].z))
			y[la]=dec(y[la],mul(v[cx[p]-cx[la]][cy[p]-cy[la]][cz[p]-cz[la]],x[p]));
	}
	printf("%d\n",x[0]);
	return 0;
}