【UOJ#129】 【NOI2015】寿司晚宴

题目描述

为了庆祝 NOI 的成功开幕,主办方为大家准备了一场寿司晚宴。小 G 和小 W 作为参加 NOI 的选手,也被邀请参加了寿司晚宴。

在晚宴上,主办方为大家提供了 n−1 种不同的寿司,编号 1,2,3,…,n−1,其中第 i 种寿司的美味度为 i+1 (即寿司的美味度为从 2 到 n)。

现在小 G 和小 W 希望每人选一些寿司种类来品尝,他们规定一种品尝方案为不和谐的当且仅当:小 G 品尝的寿司种类中存在一种美味度为 x 的寿司,小 W 品尝的寿司中存在一种美味度为 y 的寿司,而 x 与 y 不互质。

现在小 G 和小 W 希望统计一共有多少种和谐的品尝寿司的方案(对给定的正整数 p 取模)。注意一个人可以不吃任何寿司。

输入格式

输入文件的第 1 行包含 2 个正整数 n,p,中间用单个空格隔开,表示共有 n 种寿司,最终和谐的方案数要对 p 取模。

输出格式

输出一行包含 1 个整数,表示所求的方案模 p 的结果。

题解

注意到所有和谐的方案,两人的质数集合一定是不相交的。

对于所有大于根号的质数,不存在一个数同时包含两个这样的数。打个比方,假如n是100,那么我们在考虑17的时候,就不需要考虑11,13有没有取。而小于根号的质数就不具备有这个性质。所以对于大于根号的质数是一个分层的关系,层与层之间是无后效性的,所以我们可以分层来DP。

计f[i][A][B]表示在第i层里一个人集合为A,另一个人集合为B的方案。然后枚举子集、前缀和转移一下就好了。

代码

 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <cstring>
 4
 5 #define R register
 6 #define maxn 510
 7 int pr[maxn], prcnt, mp[maxn], r[maxn];
 8 int f[maxn][256][256][2], g[maxn][256][256], tf[256][256][2];
 9 bool vis[maxn];
10 inline bool cmp(R int a, R int b)
11 {
12     return mp[a] < mp[b];
13 }
14 int main()
15 {
16     R int n, p; scanf("%d%d", &n, &p);
17     for (R int i = 2; i <= n; ++i)
18     {
19         r[i] = i;
20         if (!vis[i]) pr[++prcnt] = mp[i] = i;
21         for (R int j = 1; j <= prcnt && i * pr[j] <= n; ++j)
22         {
23             vis[i * pr[j]] = 1;
24             mp[i * pr[j]] = mp[i];
25             if (i % pr[j] == 0) break;
26         }
27     }
28     std::sort(r + 2, r + n + 1, cmp);
29     R int tot = 0;
30     g[0][0][0] = 1 % p;
31     for (R int i = 2; i <= n; ++i)
32     {
33         R int x = r[i], tS = 0;
34         if (mp[x] < 20 || mp[r[i]] != mp[r[i - 1]]) ++tot;
35 //        printf("%d %d %d %d\n", i, r[i], mp[r[i]], tot);
36         for (R int j = 1; j <= prcnt && pr[j] < 20; ++j)
37             if (x % pr[j] == 0) tS |= 1 << (j - 1);
38
39         memcpy(tf, f[tot], sizeof (tf));
40         for (R int A = 0; A < 256; ++A)
41         {
42             R int mB = ~A & 255;
43             for (R int B = mB; B; B = (B - 1) & mB)
44                 if (!(B & tS))
45                     (f[tot][A | tS][B][0] += (g[tot - 1][A][B] + tf[A][B][0]) % p) %= p,
46                     (f[tot][B][A | tS][1] += (g[tot - 1][B][A] + tf[B][A][1]) % p) %= p;
47                     (f[tot][A | tS][0][0] += (g[tot - 1][A][0] + tf[A][0][0]) % p) %= p;
48                     (f[tot][0][A | tS][1] += (g[tot - 1][0][A] + tf[0][A][1]) % p) %= p;
49         }
50
51         for (R int A = 0; A < 256; ++A)
52         {
53             R int mB = ~A & 255;
54             for (R int B = mB; B; B = (B - 1) & mB)
55                 g[tot][A][B] = (g[tot - 1][A][B] + (f[tot][A][B][0] + f[tot][A][B][1]) % p) % p;
56                 g[tot][A][0] = (g[tot - 1][A][0] + (f[tot][A][0][0] + f[tot][A][0][1]) % p) % p;
57         }
58     }
59     R int ans = 0;
60     for (R int A = 0; A < 256; ++A)
61     {
62         R int mB = ~A & 255;
63         for (R int B = mB; B; B = (B - 1) & mB)
64             (ans += g[tot][A][B]) %= p;
65             (ans += g[tot][A][0]) %= p;
66     }
67     printf("%d\n", ans);
68     return 0;
69 }
时间: 2024-07-28 20:47:41

【UOJ#129】 【NOI2015】寿司晚宴的相关文章

【BZOJ4197】[Noi2015]寿司晚宴 状压DP+分解质因数

[BZOJ4197][Noi2015]寿司晚宴 Description 为了庆祝 NOI 的成功开幕,主办方为大家准备了一场寿司晚宴.小 G 和小 W 作为参加 NOI 的选手,也被邀请参加了寿司晚宴. 在晚宴上,主办方为大家提供了 n−1 种不同的寿司,编号 1,2,3,…,n−1,其中第 i 种寿司的美味度为 i+1 (即寿司的美味度为从 2 到 n). 现在小 G 和小 W 希望每人选一些寿司种类来品尝,他们规定一种品尝方案为不和谐的当且仅当:小 G 品尝的寿司种类中存在一种美味度为 x

BZOJ 4197: [Noi2015]寿司晚宴( dp )

N^0.5以内的质数只有8个, dp(i, j, k)表示用了前i个大质数(>N^0.5), 2人选的质数(<=N^0.5)集合分别为j, k时的方案数. 转移时考虑当前的大质数p是给哪个人即可. 时间复杂度O(N*2^16) ----------------------------------------------------------------- #include<cstdio> #include<cstring> #include<algorithm&

状压DP --- [NOI2015]寿司晚宴

[NOI2015]寿司晚宴 题目描述 为了庆祝NOI的成功开幕,主办方为大家准备了一场寿司晚宴. 小G和小W作为参加NOI的选手,也被邀请参加了寿司晚宴. 在晚宴上,主办方为大家提供了n?1种不同的寿司,编号1,2,3,?,n-1,其中第种寿司的美味度为i+1(即寿司的美味度为从2到n). 现在小G和小W希望每人选一些寿司种类来品尝,他们规定一种品尝方案为不和谐的当且仅当: 小G品尝的寿司种类中存在一种美味度为x的寿司,小W品尝的寿司中存在一种美味度为y的寿司,而x与y不互质. 现在小G和小W希

[UOJ#129][BZOJ4197][Noi2015]寿司晚宴

试题描述 为了庆祝 NOI 的成功开幕,主办方为大家准备了一场寿司晚宴.小 G 和小 W 作为参加 NOI 的选手,也被邀请参加了寿司晚宴. 在晚宴上,主办方为大家提供了 n?1 种不同的寿司,编号 1,2,3,-,n?1,其中第 i 种寿司的美味度为 i+1 (即寿司的美味度为从 2 到 n). 现在小 G 和小 W 希望每人选一些寿司种类来品尝,他们规定一种品尝方案为不和谐的当且仅当:小 G 品尝的寿司种类中存在一种美味度为 x 的寿司,小 W 品尝的寿司中存在一种美味度为 y 的寿司,而

[NOI2015]寿司晚宴

题目描述 为了庆祝NOI的成功开幕,主办方为大家准备了一场寿司晚宴.小G和小W作为参加NOI的选手,也被邀请参加了寿司晚宴. 在晚宴上,主办方为大家提供了n?1种不同的寿司,编号1,2,3,?,n-1,其中第种寿司的美味度为i+1(即寿司的美味度为从2到n). 现在小G和小W希望每人选一些寿司种类来品尝,他们规定一种品尝方案为不和谐的当且仅当:小G品尝的寿司种类中存在一种美味度为x的寿司,小W品尝的寿司中存在一种美味度为y的寿司,而x与y不互质. 现在小G和小W希望统计一共有多少种和谐的品尝寿司

bzoj4197 [Noi2015]寿司晚宴

Description 为了庆祝 NOI 的成功开幕,主办方为大家准备了一场寿司晚宴.小 G 和小 W 作为参加 NOI 的选手,也被邀请参加了寿司晚宴. 在晚宴上,主办方为大家提供了 n?1 种不同的寿司,编号 1,2,3,-,n?1,其中第 i 种寿司的美味度为 i+1 (即寿司的美味度为从 2 到 n). 现在小 G 和小 W 希望每人选一些寿司种类来品尝,他们规定一种品尝方案为不和谐的当且仅当:小 G 品尝的寿司种类中存在一种美味度为 x 的寿司,小 W 品尝的寿司中存在一种美味度为 y

[BZOJ]4197: [Noi2015]寿司晚宴

Time Limit: 10 Sec  Memory Limit: 512 MB Description 为了庆祝 NOI 的成功开幕,主办方为大家准备了一场寿司晚宴.小 G 和小 W 作为参加 NOI 的选手,也被邀请参加了寿司晚宴. 在晚宴上,主办方为大家提供了 n?1 种不同的寿司,编号 1,2,3,-,n?1,其中第 i 种寿司的美味度为 i+1 (即寿司的美味度为从 2 到 n). 现在小 G 和小 W 希望每人选一些寿司种类来品尝,他们规定一种品尝方案为不和谐的当且仅当:小 G 品尝

【题解】NOI2015寿司晚宴

想好久啊+不敢写啊--但果然人还是应当勇敢自信,只有坚定地去尝试,才会知道最后的结果.1A真的太开心啦,不过好像我的做法还是比较复杂的样子--理解起来应该算是比较容易好懂的类型,大家可以参考一下思路~ 首先我们先考虑一下简单的30分算法:30以内的质数只有十个左右,可以利用状压表示出两个人所选择的集合,再通过寿司转移即可.之后的大数据呢?我们发现不能这样做是因为之后的质数越来越多,状压的空间就开不下了. 这时要注意到一个性质:对于1~n内的每一个数而言,都可以分解成若干个<sqrt(n)的质数之

【bzoj4197】[Noi2015]寿司晚宴 dp

因为每个数只有一个大于根号n的质因子,所以我们把每个数拆成一个大于根号n的质因子乘以一个数的形式,对于大于根号n的质因子相同的数,我们放到一起处理 dp[0/1][i][x][y]表示A/B选了当前的大质数,现在枚举到具有当前大质数的第i个数,之前A选中的集合为x,B选中的集合为y的方案数 dp[0/1][0][x][y]=f[i-1][x][y] dp[0][i][x][y]=dp[0][i-1][x][y]+dp[0][i-1][x-S][y] dp[1][i][x][y]=dp[1][i-

bzoj 4197: [Noi2015]寿司晚宴【状压dp】

一个数内可能多个的质因数只有小于根号n的,500内这样的数只有8个,所以考虑状压 把2~n的数处理出小于根号500的质因数集压成s,以及大质数p(没有就是1),然后按p排序 根据题目要求,拥有一个质因数的只能给一个人,所以排序后能给一个人的大质数就是一个区间 然后设f[s1][s2]为一人选s1,另一人选s2的方案数,注意这里的s只压了小于根号500的八个质数 设g[0/1][s1][s2]为一人选s1,另一人选s2的,当前枚举的大质数给小G/小W的方案数 正常转移即可 然后注意把g转到f上时应