4197: [Noi2015]寿司晚宴

Time Limit: 10 Sec  Memory Limit: 512 MB
Submit: 694  Solved: 440
[Submit][Status][Discuss]

Description

为了庆祝 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 取模)。注意一个人可以不吃任何寿司。
 

Input

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

 

Output

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

 

Sample Input

3 10000

Sample Output

9

HINT

2≤n≤500

0<p≤1000000000

Source

Solution

这数据范围一眼看上去是没什么头绪的,但是可以进行一些猜想

选一个数,相当于选他的质因子,所以考虑筛一下$500$以内的质数,发现有接近$100$个,然后对于一个数$n$,它的大于等于$\sqrt n$的质因数至多有一个

然后$\sqrt 500$以内的质数只有$8$个,这就很好搞了,状压一下.

对于每个数记录它小于$\sqrt 500$以内的质因数的情况,再额外记录一下它大于$\sqrt 500$的质因数,这样就可以dp了.

显然对于大于$\sqrt 500$的质因数相同的数需要同时dp,这样分两次dp即可.

Code

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<cmath>
  5. #include<algorithm>
  6. using namespace std;
  7. #define MAXN 510
  8. int flag[MAXN],prime[MAXN],cnt;
  9. inline void Pre()
  10. {
  11. flag[1]=1;
  12. for (int i=2; i<=sqrt(500); i++)
  13. {
  14. if (!flag[i]) prime[++cnt]=i;
  15. for (int j=1; j<=cnt&&i*prime[j]<=sqrt(500); j++)
  16. {
  17. flag[i*prime[j]]=1;
  18. if (!(i%prime[j])) break;
  19. }
  20. }
  21. // for (int i=1; i<=cnt; i++) printf("%d ",prime[i]); puts("");
  22. }
  23. struct Node{int p1,p2;}a[MAXN];
  24. inline bool cmp(Node A,Node B) {return A.p2==B.p2? A.p1<B.p1:A.p2<B.p2;}
  25. int dp[1<<8][1<<8],tmp[2][1<<8][1<<8],N,ans,P;
  26. int main()
  27. {
  28. Pre();
  29. scanf("%d%d",&N,&P);
  30. for (int i=2; i<=N; i++)
  31. {
  32. int x=i;
  33. for (int j=1; j<=cnt; j++)
  34. {
  35. if (!(x%prime[j]))
  36. a[i-1].p1|=(1<<(j-1));
  37. while (!(x%prime[j])) x/=prime[j];
  38. }
  39. if (x>sqrt(500)) a[i-1].p2=x; else a[i-1].p2=0;
  40. }
  41. sort(a+1,a+N-1+1,cmp);
  42. dp[0][0]=1;
  43. int last=1;
  44. for (int i=1; i<=N-1; last++,i++)
  45. {
  46. if (a[i].p2) break;
  47. memcpy(tmp[0],dp,sizeof(tmp[0])); memcpy(tmp[1],dp,sizeof(tmp[1]));
  48. for (int j=(1<<8)-1; j>=0; j--)
  49. for (int k=(1<<8)-1; k>=0; k--)
  50. {
  51. if (!(k&a[i].p1))
  52. (tmp[0][j|a[i].p1][k]+=tmp[0][j][k])%=P;
  53. if (!(j&a[i].p1))
  54. (tmp[1][j][k|a[i].p1]+=tmp[1][j][k])%=P;
  55. }
  56. for (int j=0; j<(1<<8); j++)
  57. for (int k=0; k<(1<<8); k++)
  58. dp[j][k]=((tmp[0][j][k]+tmp[1][j][k]-dp[j][k])%P+P)%P;
  59. }
  60. while (last<N)
  61. {
  62. memcpy(tmp[0],dp,sizeof(tmp[0])); memcpy(tmp[1],dp,sizeof(tmp[1]));
  63. for (int i=last; i<=N-1; last++,i++)
  64. {
  65. for (int j=(1<<8)-1; j>=0; j--)
  66. for (int k=(1<<8)-1; k>=0; k--)
  67. {
  68. if (!(k&a[i].p1))
  69. (tmp[0][j|a[i].p1][k]+=tmp[0][j][k])%=P;
  70. if (!(j&a[i].p1))
  71. (tmp[1][j][k|a[i].p1]+=tmp[1][j][k])%=P;
  72. }
  73. if (a[i].p2!=a[i+1].p2) break;
  74. }
  75. last++;
  76. for (int j=0; j<(1<<8); j++)
  77. for (int k=0; k<(1<<8); k++)
  78. dp[j][k]=((tmp[0][j][k]+tmp[1][j][k]-dp[j][k])%P+P)%P;
  79. }
  80. for (int j=0; j<(1<<8); j++)
  81. for (int k=0; k<(1<<8); k++)
  82. if (!(j&k)) (ans+=dp[j][k])%=P;
  83. printf("%d\n",ans);
  84. return 0;
  85. }

  

【BZOJ-4197】寿司晚宴 状压DP的更多相关文章

  1. UOJ 129/BZOJ 4197 寿司晚宴 状压DP

    //By SiriusRen #include <cstdio> #include <algorithm> using namespace std; ; struct Node ...

  2. NOI 2015 寿司晚宴 (状压DP+分组背包)

    题目大意:两个人从2~n中随意取几个数(不取也算作一种方案),被一个人取过的数不能被另一个人再取.两个人合法的取法是,其中一个人取的任何数必须与另一个人取的每一个数都互质,求所有合法的方案数 (数据范 ...

  3. BZOJ 4197 NOI 2015 寿司晚宴 状压DP

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

  4. BZOJ 4197: [Noi2015]寿司晚宴 状压dp+质因数分解

    挺神的一道题 ~ 由于两个人选的数字不能有互质的情况,所以说对于一个质因子来说,如果 1 选了,则 2 不能选任何整除该质因子的数. 然后,我们发现对于 1 ~ 500 的数字来说,只可能有一个大于 ...

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

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

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

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

  7. B4197 [Noi2015]寿司晚宴 状压dp

    这个题一开始想到了唯一分解定理,然后状压.但是显然数组开不下,后来想到每个数(n<500)大于19的素因子只可能有一个,所以直接单独存就行了. 然后正常状压dp就很好搞了. 题干: Descri ...

  8. bzoj4197 [Noi2015]寿司晚宴——状压DP

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4197 首先,两个人选的数都互质可以看作是一个人选了一个数,就相当于选了一个质因数集合,另一个 ...

  9. [NOI2015][bzoj4197] 寿司晚宴 [状压dp+质因数]

    题面 传送门 思路 首先,要让两个人选的数字全部互质,那么有一个显然的充要条件:甲选的数字的质因数集合和乙选的数字的质因数集合没有交集 30pt 这种情况下n<=30,也就是说可用的质数只有10 ...

随机推荐

  1. 如何写出安全的API接口(参数加密+超时处理+私钥验证+Https)- 续(附demo)

    上篇文章说到接口安全的设计思路,如果没有看到上篇博客,建议看完再来看这个. 通过园友们的讨论,以及我自己查了些资料,然后对接口安全做一个相对完善的总结,承诺给大家写个demo,今天一并放出. 对于安全 ...

  2. mysql can't create threads in threadpool

    最近,我们在券商端的mysql运行一段时间后,发生mysql can't create threads in threadpool,如下所示: 据官网一个报告显示,目测是一个bug,内存紧张导致,那天 ...

  3. Node.js之sails框架

    先开一坑,有空更新,记录最近钉钉项目上对node及sails框架的学习记录和理解

  4. 如何为eclipse安装合适版本的python插件pydev

    pydev是一款优秀的Eclipse插件,大多数喜欢在eclipse开发软件的程序员(也许是java程序员)在开发python软件时希望继续使用eclipse,那么pydev是非常理想的选择. 1.安 ...

  5. 深入理解javascript选择器API系列第二篇——getElementsByClassName

    × 目录 [1]使用 [2]classList [3]扩展 前面的话 既然有getElementById()和getElementsByTagName()方法,为什么没有getElementsByCl ...

  6. VS2012 Unit Test —— 我对IdleTest库动的大手术以及对Xml相关操作进行测试的方式

    [1]我的IdleTest源码地址:http://idletest.codeplex.com/ [2]IdleTest改动说明:2013年10月份在保持原有功能的情况下对其动了较大的手术,首先将基本的 ...

  7. 自定义PopupWindow

    PopupWindow,一个弹出窗口控件,可以用来显示任意View,而且会浮动在当前activity的顶部 自定义PopupWindow. 1.extends PopupWindow 2.构造方法中可 ...

  8. Android开发案例 - 注册登录

    本文只涉及UI方面的内容, 如果您是希望了解非UI方面的访客, 请跳过此文. 在微博, 微信等App的注册登录过程中有这样的交互场景(如下图): 打开登录界面 在登录界面中, 点击注册, 跳转到注册界 ...

  9. 15-static和extern关键字1-对函数的作用

    一.extern与函数 如果一个程序中有多个源文件(.c),编译成功会生成对应的多个目标文件(.obj),这些目标文件还不能单独运行,因为这些目标文件之间可能会有关联,比如a.obj可能会调用c.ob ...

  10. mongodb之使用explain和hint性能分析和优化

    当你第一眼看到explain和hint的时候,第一个反应就是mysql中所谓的这两个关键词,确实可以看出,这个就是在mysql中借鉴过来的,既然是借鉴 过来的,我想大家都知道这两个关键字的用处,话不多 ...