【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;
}

  

posted @ 2020-01-06 10:23  EM-LGH  阅读(145)  评论(0编辑  收藏  举报