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

首先,两个人选的数都互质可以看作是一个人选了一个数,就相当于选了一个质因数集合,另一个人不能再选;

想把质因数状压起来,但是数量太多;

有个性质是一个数 x 最多有一个大于根号 x 的质因数,把那个拿出来单独考虑的话,剩下的质因数(小于根号500的)只有8个,可以状压;

于是先对2到 n 的每个数处理出单独的质因数和剩下的质因数状态,然后对单独质因数相同的几个数一起进行DP;

单独质因数相同,那么这几个数要么都被第一个人选,要么都被第二个人选,要么不被选;

所以用一个辅助数组 g 承接之前的 f 值,然后分成 g[0] 和 g[1] 分别表示第一个人选还是第二个人选,0和1之间不互相转移;

最后再把 f 赋回来,要注意这整个集合不被选的状态被算了两次,所以再减掉一个原来的值;

感觉自己好难想出来啊,尤其是那个辅助的 g 数组,但想好了却这么简洁。

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
int const maxn=,mx=(<<);
int n,p,pri[]={,,,,,,,};
ll f[mx][mx],g[][mx][mx],ans;
struct N{int s,num;}a[maxn];
bool cmp(N x,N y){return x.num<y.num;}
void init()
{
for(int i=;i<=n;i++)
{
int x=i;
for(int j=;j<;j++)
{
if(x%pri[j])continue;
a[i].s|=(<<j);
while(x%pri[j]==)x/=pri[j];
}
a[i].num=x;
}
}
int main()
{
scanf("%lld%lld",&n,&p);
init();
sort(a+,a+n+,cmp);//a+2
f[][]=;
for(int i=;i<=n;i++)
{
if(i==||a[i].num!=a[i-].num||a[i].num==)//1表示没有大于根号n的质因子,所以每次重新DP
memcpy(g[],f,sizeof f),memcpy(g[],f,sizeof f);
for(int j=mx-;j>=;j--)
for(int k=mx-;k>=;k--)//倒序
{
if(j&k)continue;
if(!(a[i].s&k)) (g[][j|a[i].s][k]+=g[][j][k])%=p;
if(!(a[i].s&j)) (g[][j][k|a[i].s]+=g[][j][k])%=p;
}
if(i==n||a[i].num!=a[i+].num||a[i].num==)
{
for(int j=mx-;j>=;j--)
for(int k=mx-;k>=;k--)
// if(!(j&k)) (f[j][k]+=g[0][j][k]+g[1][j][k]-f[j][k])%=p;//已把之前f的值赋给g
if(!(j&k)) (f[j][k]=(g[][j][k]+g[][j][k]-f[j][k])%p+p)%p;//+p%p
}
}
for(int j=mx-;j>=;j--)
for(int k=mx-;k>=;k--)
if(!(j&k)) (ans+=f[j][k])%=p;
printf("%lld\n",ans);
return ;
}

bzoj4197 [Noi2015]寿司晚宴——状压DP的更多相关文章

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

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

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

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

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

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

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

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

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

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

  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. NOI 2015 寿司晚宴 (状压DP+分组背包)

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

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

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

随机推荐

  1. Angular——内置指令

    内置指令 ng-app 指定应用根元素,至少有一个元素指定了此属性. ng-controller 指定控制器 ng-show控制元素是否显示,true显示.false不显示 ng-hide控制元素是否 ...

  2. JS高级——词法作用域

    作用域 1.js中没有块级作用域 2.如果有块级作用域,那么下面代码将会是undefined undefined <script> for (var i = 0; i < 10; i ...

  3. CSS——float

    float:就是在于布局,首先要介绍的是文档流(标准流),之后是浮动布局. 文档流:元素自上而下,自左而右,块元素独占一行,行内元素在一行上显示,碰到父集元素的边框换行. 浮动布局: 1.float: ...

  4. 【译】x86程序员手册04 - 2.2数据类型

    2.2 Data Types 数据类型 Bytes, words, and doublewords are the fundamental data types (refer to Figure 2- ...

  5. 预处理、const、static、sizeof

    1.预处理和宏定义 #define xxxx #ifdef xxxx ; #elseif xxxx; #endif 2.c++求随机数 rand(),rand()会返回一随机数值, 范围在0至RAND ...

  6. logstash windows下添加服务启动管理

    nssm下载链接:http://nssm.cc/release/nssm-2.24.zip

  7. if判断,while循环,for循环

    if判断 if判断其实就是让计算机模拟人的判断 if if 条件: 代码1 代码2 代码3 ... # 代码块(同一缩进级别的代码,例如代码1.代码2和代码3是相同缩进的代码,这三个代码组合在一起就是 ...

  8. java 异常报错总结

    1.java.lang.ArithmeticException:这是算数异常 比如分母位0 2. java.lang.ArrayIndexOutOfBoundsException:数组下标越界异常 3 ...

  9. 微信小程序支付(JSAPI支付)

    开发环境:.NET MVC+ ORM框架(EF) 一.参考文档: 1.微信JSAPI支付官方文档:https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api. ...

  10. golang bytes 包

    类型 []byte 的切片十分常见,Go 语言有一个 bytes 包专门用来解决这种类型的操作方法. bytes 包和字符串包十分类似.而且它还包含一个十分有用的类型 Buffer: import & ...