今年NOI确实是在下输了。最近想把当时不会做的题都写一下。

题意

从2到n(500)这些数字中,选若干分给A,若干分给B,满足不存在:A的某个数和B的某个数的GCD不等于1。

对于寿司晚宴这题,标准解答确实是有个神奇的DP。

算法

我们要关注的只是所有的质数。最简单的想法就是枚举A,B各获得哪些数。但是质数的数量实在比较多。然后有个技巧就是将小于\(\sqrt n\)的质数和大于\(\sqrt n\)的数分开处理。这样做的原因是一个数最多只能有一个大于\(\sqrt n\)的质因数。

这样的话,小于\(\sqrt n\)的质数就只有8个了。状态压缩DP或者容斥,就能在\(O(2^8 \times 2^8 n)\)内计算出,A获得的质数集合是x(状态压缩为一整数),B获得的质数集合是y时,有多少种方案,记为f(x, y)。注意,这里的方案并没有计算含有大于\(\sqrt n\)的质因数的数字

接下来,我们要把这些数字也算入答案。奇妙的DP就在这里体现了。

我们只要枚举大于\(\sqrt n\)的那些质数p,一个一个累加到f里,就可以得到最终的答案了。

设g(i, x, y)表示将\(ip\)这个数字分出去后(或者不分给任何人),A获得的质数集合是x,B获得的质数集合是y的方案数。那么,考虑下一个数\((i+1)p\),分给A(分给B同理):

\[g(i + 1, add(x, (i+1)p), y) = g(i, x, y) + f(x, y)
\]

add(x, num)表示将num这个数加进去后,x的变化。


我可能说得不是很清楚,但这毕竟我是打算自己看的。

代码

#include <bits/stdc++.h>
using namespace std; int n, MOD; const int prime[] = {2, 3, 5, 7, 11, 13, 17, 19}; void clear(int (*array)[256]) {
memset(array, 0, sizeof(int) * 256 * 256);
} void copy(int (*src)[256], int (*dest)[256]) {
memcpy(dest, src, sizeof(int) * 256 * 256);
} void add(int &x, int delta) {
if (delta >= MOD) delta -= MOD;
x += delta;
if (x >= MOD) x -= MOD;
} int main() {
scanf("%d%d", &n, &MOD); static int devide[503];
for (int j = 1; j <= n; j++) {
int ret = 0;
int num = j;
for (int i = 0; i < 8; i++) {
int x = prime[i];
while (num % x == 0) {
num /= x;
ret |= 1 << i;
}
}
if (num == 1) devide[j] = ret;
else devide[j] = ret ? -2 : -1;
} static int dp[2][256][256];
int (*cur)[256] = dp[0];
int (*next)[256] = dp[1]; cur[0][0] = 1;
for (int i = 2; i <= n; i++) {
int s = devide[i];
if (s < 0) continue;
copy(cur, next);
for (int a = 0; a < 256; a++)
for (int b = 0; b < 256; b++) {
int &x = cur[a][b];
if (x) {
if (! (s & b)) add(next[a | s][b], x);
if (! (s & a)) add(next[a][b | s], x);
}
}
swap(next, cur);
} static int f[256][256];
for (int i = 23; i <= n; i++) {
if (devide[i] != -1) continue;
clear(f);
for (int j = 1; j * i <= n; j++) {
int s = devide[j];
for (int a = 255; a >= 0; a--)
for (int b = 255; b >= 0; b--) {
if (! (s & b)) add(f[a | s][b], f[a][b] + cur[a][b]);
}
}
for (int a = 0; a < 256; a++)
for (int b = 0; b < 256; b++)
add(cur[a][b], f[a][b] + f[b][a]);
} int ans = 0;
for (int a = 0; a < 256; a++)
for (int b = 0; b < 256; b++)
add(ans, cur[a][b]);
printf("%d\n", ans); return 0;
}

NOI2015 寿司晚宴的更多相关文章

  1. [BZOJ4197][Noi2015]寿司晚宴

    4197: [Noi2015]寿司晚宴 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 412  Solved: 279[Submit][Status] ...

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

    N^0.5以内的质数只有8个, dp(i, j, k)表示用了前i个大质数(>N^0.5), 2人选的质数(<=N^0.5)集合分别为j, k时的方案数. 转移时考虑当前的大质数p是给哪个 ...

  3. BZOJ_4197_[Noi2015]寿司晚宴_状态压缩动态规划

    BZOJ_4197_[Noi2015]寿司晚宴_状态压缩动态规划 Description 为了庆祝 NOI 的成功开幕,主办方为大家准备了一场寿司晚宴.小 G 和小 W 作为参加 NOI 的选手,也被 ...

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

    [NOI2015]寿司晚宴 题目描述 为了庆祝NOI的成功开幕,主办方为大家准备了一场寿司晚宴. 小G和小W作为参加NOI的选手,也被邀请参加了寿司晚宴. 在晚宴上,主办方为大家提供了n−1种不同的寿 ...

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

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

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

    [UOJ#129][BZOJ4197][Noi2015]寿司晚宴 试题描述 为了庆祝 NOI 的成功开幕,主办方为大家准备了一场寿司晚宴.小 G 和小 W 作为参加 NOI 的选手,也被邀请参加了寿司 ...

  7. BZOJ 4197: [Noi2015]寿司晚宴 状态压缩 + 01背包

    4197: [Noi2015]寿司晚宴 Time Limit: 10 Sec  Memory Limit: 512 MB Description 为了庆祝 NOI 的成功开幕,主办方为大家准备了一场寿 ...

  8. bzoj 4199 [NOI2015]寿司晚宴

    Description 为了庆祝 NOI 的成功开幕,主办方为大家准备了一场寿司晚宴.小 G 和小 W 作为参加 NOI 的选手,也被邀请参加了寿司晚宴. 在晚宴上,主办方为大家提供了 n−1 种不同 ...

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

    Time Limit: 10 Sec  Memory Limit: 512 MB Description 为了庆祝 NOI 的成功开幕,主办方为大家准备了一场寿司晚宴.小 G 和小 W 作为参加 NO ...

随机推荐

  1. 如何用python抓取js生成的数据 - SegmentFault

    如何用python抓取js生成的数据 - SegmentFault 如何用python抓取js生成的数据 1赞 踩 收藏 想写一个爬虫,但是需要抓去的的数据是js生成的,在源代码里看不到,要怎么才能抓 ...

  2. js 精美倒计时

    精美倒计时*{ padding:0; margin:0;}.colockbox{width:250px;height:30px;background:url(/jscss/demoimg/201312 ...

  3. 分蛋糕(C - 二分查找)

    分蛋糕 题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=85904#problem/C Description My birthd ...

  4. hdu 3625 第一类striling 数

    /** 第一类Stirling数是有正负的,其绝对值是包含n个元素的集合分作k个环排列的方法数目. 递推公式为, S(n,0) = 0, S(1,1) = 1. S(n+1,k) = S(n,k-1) ...

  5. (Problem 22)Names scores

    Using names.txt (right click and 'Save Link/Target As...'), a 46K text file containing over five-tho ...

  6. box-shadow 被其他div遮住 shadow was hidden/covered by another div

    使用z-index 来处理 (z-index必须在使用了position的情况下才有效) 参考http://stackoverflow.com/questions/5505118/css-box-sh ...

  7. Linux学习:curl 与 wget命令

    curl和wget命令都是Linux下的工具,可以用来下载文件. 一.wget 例1: wget http://www.minjieren.com/wordpress-3.1-zh_CN.zip 下载 ...

  8. Uva 572 Oil Deposits

    思路:可以用DFS求解.遍历这个二维数组,没发现一次未被发现的‘@’,便将其作为起点进行搜索.最后的答案,是这个遍历过程中发现了几次为被发现的‘@’ import java.util.*; publi ...

  9. pxe网络安装操作系统 原理与详细过程

    摘要:在实际工作中,我们经常会遇到这样的情况:想要安装Linux但是计算机不带光驱或软驱,或者是笔记本配置的非标准的软驱和光驱,如1394接口,USB接口等,在Linux安装时所引导的Linux内核一 ...

  10. 一个轻client,多语言支持,去中心化,自己主动负载,可扩展的实时数据写服务的实现方案讨论

    背景 背景是设计一个实时数据接入的模块,负责接收client的实时数据写入(如日志流,点击流),数据支持直接下沉到HBase上(兴许提供HBase上的查询),或先持久化到Kafka里.方便兴许进行一些 ...