挺神的一道题 ~

由于两个人选的数字不能有互质的情况,所以说对于一个质因子来说,如果 1 选了,则 2 不能选任何整除该质因子的数.

然后,我们发现对于 1 ~ 500 的数字来说,只可能有一个大于 $\sqrt 500$ 的质因子(两个的话乘积就超过 500 了)

而不大于 $\sqrt 500$ 的质因子总数只有 8 个,所以可以对这 8 个质因子状压.

我们先假设所有数字都 $\eqslant 30$,即所有质因子都 $leqslant \sqrt 500$.

定义状态 dp[i][j] 表示第一个人选的质因子集合为 $i$,第二个人选的质因子集合为 $j$.

那么直接更新 $dp[i|sta][j]+=dp[i][j]$ (sta 与 k 无交集)

对于第二个维度同理.

由于我们用滚动数组,所以还要定义 f1[i][j], f2[i][j] 表示第一个人/第二个人 和 第二个人/第一个人 状态下的方案数.

这个转移弄完之后,我们再考虑加入大于 $\sqrt 500$ 的质因子的情况:

令这个质因子为 $x$,那么会有一段数字都包含这个 $x$,显然这些数中只能让 1 个人去选择这个质因子.

我们沿用上面那个 f1[i][j], f2[i][j] 来更新,然后对于这一段的开始位置直接令 f1=f2=dp,其余的正常 dp。

处理完这段的时候还要减去两个数都不选的情况.

最后 dp'[i][j]=f1[i][j]+f2[i][j]-dp[i][j].

code:

  1. #include <bits/stdc++.h>
  2. #define N 703
  3. #define LL long long
  4. #define setIO(s) freopen(s".in","r",stdin)
  5. using namespace std;
  6. int n;
  7. int poww[N];
  8. LL ans,mod;
  9. LL dp[N][N],f1[N][N],f2[N][N];
  10. int p[13]={0,2,3,5,7,11,13,17,19,23};
  11. struct data
  12. {
  13. int num,bi,sta;
  14. }a[N];
  15. bool cmp(data a,data b)
  16. {
  17. return a.bi<b.bi;
  18. }
  19. void init(int num)
  20. {
  21. int i,j,v=num,bi=0;
  22. for(i=1;i<=8;++i)
  23. {
  24. if(v%p[i]==0)
  25. {
  26. a[num].sta|=poww[i];
  27. while(v%p[i]==0) v/=p[i];
  28. }
  29. }
  30. if(v>1) bi=v;
  31. a[num].bi=bi;
  32. a[num].num=num;
  33. }
  34. int main()
  35. {
  36. // setIO("input");
  37. int i,j;
  38. scanf("%d%lld",&n,&mod);
  39. for(i=1;i<=12;++i) poww[i]=(1<<(i-1));
  40. for(i=2;i<=n;++i) init(i);
  41. sort(a+2,a+1+n,cmp);
  42. dp[0][0]=1ll;
  43. for(i=2;i<=n;++i)
  44. {
  45. if(i==2||!a[i].bi||a[i].bi!=a[i-1].bi)
  46. {
  47. memcpy(f1,dp,sizeof(dp));
  48. memcpy(f2,dp,sizeof(dp));
  49. }
  50. for(j=255;j>=0;--j)
  51. {
  52. for(int k=255;k>=0;--k)
  53. {
  54. if((j&a[i].sta)==0) f1[j][k|a[i].sta]=(f1[j][k|a[i].sta]+f1[j][k])%mod;
  55. if((k&a[i].sta)==0) f2[j|a[i].sta][k]=(f2[j|a[i].sta][k]+f2[j][k])%mod;
  56. }
  57. }
  58. if(i==n||!a[i].bi||a[i].bi!=a[i+1].bi)
  59. {
  60. for(j=0;j<=255;++j)
  61. {
  62. for(int k=0;k<=255;++k)
  63. {
  64. dp[j][k]=(f1[j][k]+f2[j][k]-dp[j][k]+mod)%mod;
  65. }
  66. }
  67. }
  68. }
  69. LL ans=0ll;
  70. for(i=0;i<=255;++i) for(j=0;j<=255;++j) if((i&j)==0) (ans+=dp[i][j])%=mod;
  71. printf("%lld\n",ans);
  72. return 0;
  73. }

  

BZOJ 4197: [Noi2015]寿司晚宴 状压dp+质因数分解的更多相关文章

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

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

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

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

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

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

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

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

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

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

  6. [NOI2015]寿司晚宴——状压dp

    题目转化:将2~n的数分成两组,可以不选,使得这两组没有公共的质因子.求方案数. 选择了一个数,相当于选择了它的所有质因子. 30分: 发现,n<=30的时候,涉及到的质因子也就10个.2,3, ...

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

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

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

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

  9. 【BZOJ-4197】寿司晚宴 状压DP

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

随机推荐

  1. 深度学习-DCGAN论文的理解笔记

    训练方法DCGAN 的训练方法跟GAN 是一样的,分为以下三步: (1)for k steps:训练D 让式子[logD(x) + log(1 - D(G(z)) (G keeps still)]的值 ...

  2. scratch少儿编程第一季——09、声音模块:吹拉弹唱我也会

    各位小伙伴大家好: 上期我们学习了外观模块的指令,学会了制作特效. 本期我们来学习如何给游戏配音. 声音模块的指令不是很多,我们一起来看看吧. 首先第一个就是播放声音,里面默认插入了喵叫声. 我们点击 ...

  3. Locust性能测试-环境准备与基本使用 转自:悠悠

    前言 提到性能测试,大部分小伙伴想到的就是LR和jmeter这种工具,小编一直不太喜欢写这种工具类的东西,我的原则是能用代码解决的问题,尽量不去用工具. python里面也有一个性能测试框架Locus ...

  4. 在local模式下的spark程序打包到集群上运行

    一.前期准备 前期的环境准备,在Linux系统下要有Hadoop系统,spark伪分布式或者分布式,具体的教程可以查阅我的这两篇博客: Hadoop2.0伪分布式平台环境搭建 Spark2.4.0伪分 ...

  5. ODBC数据导入

    这个方法其实是导入excel 首先进入pl/sql dev (1):tools-->ODBC importer (2):点击connect,选择需要导入的excel (3):如果事先数据库中没有 ...

  6. 关于ElasticSearch的堆内存设置与优化

    1.什么是堆内存?Java 中的堆是 JVM 所管理的最大的一块内存空间,主要用于存放各种类的实例对象.在 Java 中,堆被划分成两个不同的区域:- 新生代 ( Young ).- 老年代 ( Ol ...

  7. 什么才是JavaEE基础

    近日里,很多人邀请我回答各种j2ee开发的初级问题,我无一都强调java初学者要先扎实自己的基础知识,那什么才是java的基础知识?又怎么样才算掌握了java的基础知识呢?这个问题还真值得仔细思考. ...

  8. quartz与c3p0冲突

    在SSM中使用连接池c3p0正常,引入quartz后发现后台报错 java.lang.AbstractMethodError: Method com/mchange/v2/c3p0/impl/NewP ...

  9. Java File类 mkdir 不能创建多层目录

    File f = new File("/home/jp/Upload"); if ((!f.exists()) || (!f.isDirectory())) {boolean re ...

  10. form表单的密码是否一致校验功能

    这是form类表单,自定义的form表单,需要重写钩子函数 """ forms类表单 """ # 校验密码是否一致 from django. ...