【luogu3734】 [HAOI2017]方案数 组合计数
code:
#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
#define N 66
#define ll long long
#define mod 998244353
using namespace std;
ll lowbit(ll t) { return t&(-t); }
int count(ll x)
{
int tmp=0;
for(;x;x-=lowbit(x)) ++tmp;
return tmp;
}
struct node
{
ll x,y,z;
}p[100007];
bool cmp(node a,node b) { return (a.x==b.x&&a.y==b.y)?(a.z<b.z):(a.x==b.x?a.y<b.y:a.x<b.x);}
ll n,m,r;
int f[N][N][N],C[N][N],g[100007];
void setIO(string s) { freopen((s+".in").c_str(),"r",stdin); }
int main()
{
// setIO("input");
int i,j,o;
scanf("%lld%lld%lld%d",&n,&m,&r,&o);
for(i=1;i<=o;++i) scanf("%lld%lld%lld",&p[i].x,&p[i].y,&p[i].z);
++o;
p[o].x=n,p[o].y=m,p[o].z=r;
sort(p+1,p+1+o,cmp);
f[0][0][0]=1,C[0][0]=1;
for(i=1;i<=64;++i)
{
C[i][0]=1;
for(j=1;j<=i;++j) C[i][j]=(ll)(C[i-1][j]+C[i-1][j-1])%mod;
}
for(i=0;i<=64;++i)
{
for(j=0;j<=64;++j)
{
for(int k=0;k<=64;++k)
{
if(i)
{
for(int l=1;l<=i;++l)
f[i][j][k]=(ll)(f[i][j][k]+(ll)f[i-l][j][k]*C[i][l]%mod)%mod;
}
if(j)
{
for(int l=1;l<=j;++l)
f[i][j][k]=(ll)(f[i][j][k]+(ll)f[i][j-l][k]*C[j][l]%mod)%mod;
}
if(k)
{
for(int l=1;l<=k;++l)
f[i][j][k]=(ll)(f[i][j][k]+(ll)f[i][j][k-l]*C[k][l]%mod)%mod;
}
}
}
}
for(i=1;i<=o;++i)
{
ll x=p[i].x,y=p[i].y,z=p[i].z;
g[i]=f[count(x)][count(y)][count(z)];
for(j=1;j<i;++j)
{
ll x1=p[j].x,y1=p[j].y,z1=p[j].z;
if((x1&x)!=x1||(y1&y)!=y1||(z1&z)!=z1) continue;
int bx=count(x^x1),by=count(y^y1),bz=count(z^z1);
g[i]=(ll)((ll)(g[i]-(ll)g[j]*f[bx][by][bz]%mod)+mod)%mod;
}
}
printf("%d\n",g[o]);
return 0;
}

浙公网安备 33010602011771号