bzoj4197 [Noi2015]寿司晚宴——状压DP
题目: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的更多相关文章
- 【BZOJ4197】[Noi2015]寿司晚宴 状压DP+分解质因数
[BZOJ4197][Noi2015]寿司晚宴 Description 为了庆祝 NOI 的成功开幕,主办方为大家准备了一场寿司晚宴.小 G 和小 W 作为参加 NOI 的选手,也被邀请参加了寿司晚宴 ...
- 【BZOJ-4197】寿司晚宴 状压DP
4197: [Noi2015]寿司晚宴 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 694 Solved: 440[Submit][Status] ...
- [NOI2015]寿司晚宴 --- 状压DP
[NOI2015]寿司晚宴 题目描述 为了庆祝NOI的成功开幕,主办方为大家准备了一场寿司晚宴. 小G和小W作为参加NOI的选手,也被邀请参加了寿司晚宴. 在晚宴上,主办方为大家提供了n−1种不同的寿 ...
- B4197 [Noi2015]寿司晚宴 状压dp
这个题一开始想到了唯一分解定理,然后状压.但是显然数组开不下,后来想到每个数(n<500)大于19的素因子只可能有一个,所以直接单独存就行了. 然后正常状压dp就很好搞了. 题干: Descri ...
- BZOJ 4197: [Noi2015]寿司晚宴 状压dp+质因数分解
挺神的一道题 ~ 由于两个人选的数字不能有互质的情况,所以说对于一个质因子来说,如果 1 选了,则 2 不能选任何整除该质因子的数. 然后,我们发现对于 1 ~ 500 的数字来说,只可能有一个大于 ...
- [NOI2015]寿司晚宴——状压dp
题目转化:将2~n的数分成两组,可以不选,使得这两组没有公共的质因子.求方案数. 选择了一个数,相当于选择了它的所有质因子. 30分: 发现,n<=30的时候,涉及到的质因子也就10个.2,3, ...
- BZOJ 4197 NOI 2015 寿司晚宴 状压DP
4197: [Noi2015]寿司晚宴 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 694 Solved: 440[Submit][Status] ...
- NOI 2015 寿司晚宴 (状压DP+分组背包)
题目大意:两个人从2~n中随意取几个数(不取也算作一种方案),被一个人取过的数不能被另一个人再取.两个人合法的取法是,其中一个人取的任何数必须与另一个人取的每一个数都互质,求所有合法的方案数 (数据范 ...
- [NOI2015][bzoj4197] 寿司晚宴 [状压dp+质因数]
题面 传送门 思路 首先,要让两个人选的数字全部互质,那么有一个显然的充要条件:甲选的数字的质因数集合和乙选的数字的质因数集合没有交集 30pt 这种情况下n<=30,也就是说可用的质数只有10 ...
随机推荐
- Kafka 入门和 Spring Boot 集成
目录 Kafka 入门和 Spring Boot 集成 标签:博客 概述 应用场景 基本概念 基本结构 和Spring Boot 集成 集成概述 集成环境 kafka 环境搭建 Spring Boot ...
- Qt 窗体间传值(代码备份)
刚开始看的时候看的云里雾里的,现在稍微明白一点了.现在假设有一个form,一个MainWindow,如图所示: 实现点击PushButton,将文本框中的内容传输到MainWindow中,显示为Lab ...
- Ubuntu 常用解压与压缩命令
参考 https://blog.csdn.net/songbinxu/article/details/80435665 示例: 把/home/wangju/gitlab/automationTest目 ...
- UpdateData
UpdateData 类似于C语言的scanf printf函数 管理控件与关联变量之间的数据更新. updatedata(true)把界面输入的数值更新到关联变量中,updatedata(false ...
- VM虚拟机NAT链接外网
1.vi /etc/sysconfig/networkNETWORKING=yesHOSTNAME=localhost.localdomainGATEWAY=192.168.110.2 2.vi /e ...
- 【转载】resolv.conf中search作用
原文地址:http://www.oliver.ren/linux/387.html reslov.conf中的search主要是用来补全hostname的,有时候域名太长,可以做一个短域名做主机名字, ...
- 笔记,js对象浅析
学习笔记, 来源:http://www.cnblogs.com/zuiyirenjian/p/3535126.html 作者:醉意人间 此外,关于自运行函数可参考 http://benalman. ...
- NOIP2018 滚粗记
Day -2 上午,大家都在复习各种模板,zhx总结了足足67个模板(杨辉三角也算模板???),lgl死磕FFT发现cos和sin打反了,我也是复习板子和以前做过的题,几乎没有人颓. 接着jdr,l ...
- 消除input框的默认样式
input, button, select, textarea { outline: none; -webkit-appearance: none; border-radius: 0; } outli ...
- pyhton 网络爬取软考题库保存text
#-*-coding:utf-8-*-#参考文档#https://www.crummy.com/software/BeautifulSoup/bs4/doc/index.zh.html#find-al ...