[NOI 2015] 寿司晚宴

[题目链接]

           https://www.lydsy.com/JudgeOnline/problem.php?id=4197

[算法]

         状压DP

[代码]

         

#include<bits/stdc++.h>
using namespace std;
#define MAXN 510
typedef long long ll;
const int MAXS = (1 << 8) - 1;
const int prime[10] = {0,2,3,5,7,11,13,17,19};

int i,j,k,n,p,ans,cnt,tmp;
int bit[MAXN];
ll f[MAXS + 10][MAXS + 10];
ll g[2][MAXS + 10][MAXS + 10];
pair<int,int> a[MAXN];

namespace IO
{
    template <typename T> inline void read(T &x)
    {
            int f = 1; x = 0;
            char c = getchar();
            for (; !isdigit(c); c = getchar())
            {
                    if (c == '-') f = -f;
            }    
            for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0';
            x *= f;
    }        
    template <typename T> inline void write(T x)
    {
            if (x < 0)
            {
                    putchar('-');
                    x = -x;
            }
            if (x > 9) write(x / 10);
            putchar(x % 10 + '0');
    }
    template <typename T> inline void writeln(T x)
    {
            write(x);
            puts("");
    }
} ;
inline void divide(int x)
{
        int i,tmp = x;
        for (i = 1; i <= 8; i++)
        {
            while (tmp % prime[i] == 0)
            {
                tmp /= prime[i];
                bit[x] |= (1 << (i - 1));
            }
        }
        a[++cnt] = make_pair(tmp,bit[x]);
}

int main() 
{
        
        IO :: read(n); IO :: read(p);
        for (i = 2; i <= n; i++) divide(i);
        sort(a + 1,a + cnt + 1);
        f[0][0] = 1;
        for (i = 1; i <= cnt; i++)
        {
            if (i == 1 || a[i].first == 1 || a[i].first != a[i - 1].first)
            {
                memcpy(g[0],f,sizeof(g[0]));
                memcpy(g[1],f,sizeof(g[1]));
            }
            for (j = MAXS; j >= 0; j--)
            {
                for (k = MAXS; k >= 0; k--)
                {
                    if ((k & a[i].second) == 0)
                        g[0][j | a[i].second][k] = (g[0][j | a[i].second][k] + g[0][j][k]) % p;
                    if ((j & a[i].second) == 0) 
                        g[1][j][k | a[i].second] = (g[1][j][k | a[i].second] + g[1][j][k]) % p;
                }
            }
            if (i == cnt || a[i].first == 1 || a[i].first != a[i + 1].first)
            {
                for (j = MAXS; j >= 0; j--)
                {
                    for (k = MAXS; k >= 0; k--)
                    {
                        f[j][k] = ((g[0][j][k] + g[1][j][k] - f[j][k]) % p + p) % p;
                    }
                }
            }
        }
        for (i = 0; i <= MAXS; i++)
        {
            for (j = 0; j <= MAXS; j++)
            {
                if ((i & j) != 0) continue;
                ans = (ans + f[i][j]) % p;
            }
        }
        IO :: writeln(ans);
        
        return 0;
    
}

猜你喜欢

转载自www.cnblogs.com/evenbao/p/9460550.html