【BZOJ4197】[Noi2015]寿司晚宴 状压DP+分解质因数
【BZOJ4197】[Noi2015]寿司晚宴
Description
为了庆祝 NOI 的成功开幕,主办方为大家准备了一场寿司晚宴。小 G 和小 W 作为参加 NOI 的选手,也被邀请参加了寿司晚宴。
Input
输入文件的第 1 行包含 2 个正整数 n,p,中间用单个空格隔开,表示共有 n 种寿司,最终和谐的方案数要对 p 取模。
Output
输出一行包含 1 个整数,表示所求的方案模 p 的结果。
Sample Input
Sample Output
HINT
2≤n≤500
题解:我们考虑每个素数,它要么在A中,要么在B中,要么都不在。我们定义<sqrt(500)(更具体的说是<=19,因为23*29>500)的质数为小质数,其余的为大质数,则2-n中的任意一个数都可以表示成1(或0)个大质数*若干个小质数。因此我们可以状压小质数,枚举大质数。
用g[0或1][x][y]表示当前的大质数在A或B中,A的小质数状态为x,B的小质数状态为y的方案数。我们预处理出对于每个大质数,可以和它搭配的 小质数组 有哪些(其实就是枚举一个大质数p的所有倍数,将所有倍数都分解质因数)。如果当前这个数要被A选,相当于A既要选这个大质数也要选这个 小质数组 ,并且B既不能选这个大质数也不能选这个 小质数组 中的任一个质数。我们设这个 小质数组 的状态为S,得到DP方程:
g[0][x|S][y]=g[0][x|S][y]+g[0][x][y]
g[1][x][y|S]=g[1][x][y|S]+g[1][x][y]
我们用f[x][y]统计答案,但是发现存在重复的情况。你可以理解为虽然这个数被A抢走了,使得B不能选这个数,但是A也不想选这个数。或者这个数被B抢走了,但是B也不想选。那么重复的方案数是多少呢?就是之前的f[x][y]。所以新的f[x][y]=g[0][x][y]+g[1][x][y]-旧的f[x][y]。
同时,对于不包含大质数的数,要特殊处理。对于不同的大质数,用乘法原则统计答案(因为A可以把好多大质数都抢走);对于不同的小质数选择方法,用加法原则统计答案(小质数不能既给A又给B);DP的时候要时刻满足x&y==0。(以上都是只有本蒟蒻才不明白的地方。)
#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
using namespace std;
int n,mod,ans;
int f[1<<8][1<<8],g[2][1<<8][1<<8];
int p2[510];
int pri[]={2,3,5,7,11,13,17,19};
vector<int> v[510];
int getpri(int x)
{
int i,ret=0;
for(i=0;i<8;i++)
{
if(x%pri[i]==0)
{
ret|=(1<<i);
while(x%pri[i]==0) x/=pri[i];
}
}
v[x].push_back(ret);
}
int main()
{
scanf("%d%d",&n,&mod);
int i,j,x,y;
for(i=2;i<=n;i++) getpri(i);
f[0][0]=1;
for(j=0;j<v[1].size();j++)
{
for(x=(1<<8)-1;~x;x--)
{
for(y=(1<<8)-1;~y;y--) if(!(x&y))
{
if(!(y&v[1][j])) f[x|v[1][j]][y]=(f[x|v[1][j]][y]+f[x][y])%mod;
if(!(x&v[1][j])) f[x][y|v[1][j]]=(f[x][y|v[1][j]]+f[x][y])%mod;
}
}
}
for(i=23;i<=n;i++)
{
if(!v[i].size()) continue;
for(x=0;x<(1<<8);x++) for(y=0;y<(1<<8);y++) if(!(x&y)) g[0][x][y]=g[1][x][y]=f[x][y];
for(j=0;j<v[i].size();j++)
{
for(x=(1<<8)-1;~x;x--)
{
for(y=(1<<8)-1;~y;y--) if(!(x&y))
{
if(!(y&v[i][j])) g[0][x|v[i][j]][y]=(g[0][x|v[i][j]][y]+g[0][x][y])%mod;
if(!(x&v[i][j])) g[1][x][y|v[i][j]]=(g[1][x][y|v[i][j]]+g[1][x][y])%mod;
}
}
}
for(x=0;x<(1<<8);x++) for(y=0;y<(1<<8);y++) f[x][y]=((g[0][x][y]+g[1][x][y]-f[x][y])%mod+mod)%mod;
}
for(x=0;x<(1<<8);x++) for(y=0;y<(1<<8);y++) ans=(ans+f[x][y])%mod;
printf("%d",ans);
return 0;
}
【BZOJ4197】[Noi2015]寿司晚宴 状压DP+分解质因数的更多相关文章
- bzoj4197 [Noi2015]寿司晚宴——状压DP
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4197 首先,两个人选的数都互质可以看作是一个人选了一个数,就相当于选了一个质因数集合,另一个 ...
- 【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种不同的寿 ...
- BZOJ 4197: [Noi2015]寿司晚宴 状压dp+质因数分解
挺神的一道题 ~ 由于两个人选的数字不能有互质的情况,所以说对于一个质因子来说,如果 1 选了,则 2 不能选任何整除该质因子的数. 然后,我们发现对于 1 ~ 500 的数字来说,只可能有一个大于 ...
- B4197 [Noi2015]寿司晚宴 状压dp
这个题一开始想到了唯一分解定理,然后状压.但是显然数组开不下,后来想到每个数(n<500)大于19的素因子只可能有一个,所以直接单独存就行了. 然后正常状压dp就很好搞了. 题干: Descri ...
- [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 ...
随机推荐
- Ueditor 在线编辑器使用
ueditor在线编辑器插件 地址:http://ueditor.baidu.com/website/ 试用体验: 帮助文档:http://fex.baidu.com/ueditor/ 实操 引入 ...
- schema设计
Schema设计 Schema:表的模式: 设计数据的表,索引,以及表和表的关系 在数据建模的基础上将关系模型转为数据库表 满足业务模型需要基础上根据数据库和应用特点优化表结构 关系模型图 ...
- php正则表达式取子字符串及替换
最近在学习如何用php编写cms,想把文章中的第一个图片提取出来当做缩略图显示到前面,想到的方法就是把文章内容作为一个大字符串,然后用正则表达式找出匹配出第一次出现<img src=" ...
- curl的用法
1.官网:https://curl.haxx.se/ 2.版本安全漏洞:https://curl.haxx.se/docs/security.html 3.github:https://github. ...
- Linux 设备驱动模型
Linux系统将设备和驱动归一到设备驱动模型中了来管理 设备驱动程序功能: 1,对硬件设备初始化和释放 2,对设备进行管理,包括实参设置,以及提供对设备的统一操作接口 3,读取应用程序传递给设备文件的 ...
- 在C#中使用C++编写的类——用托管C++进行封装[转]
现在在Windows下的应用程序开发,VS.Net占据了绝大多数的份额.因此很多以前搞VC++开发的人都转向用更强大的VS.Net.在这种情况 下,有很多开发人员就面临了如何在C#中使用C++开发好的 ...
- EXCEL最大行数问题:org.apache.xmlbeans.impl.store.Saver$TextSaver.resize(Saver.java:1700)
今天在使用POI导出数据时,出现如下错误: ES查询阅读推荐比: resList: start: 写入excel Exception in thread "main" java.l ...
- JNI开发(2)——开发实战
JNI开发(1)--概述.环境搭建.必要知识点 JNI开发(2)--开发实战 本篇是重头戏:JNI实战开发.假设你对于 JNI.NDK 还没概念的话 那么观看本篇 也是没有太大难度的 ,哈哈哈哈! ! ...
- hdu1595 find the longest of the shortest(Dijkstra)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1595 find the longest of the shortest Time Limit: 100 ...
- 转载:JAVA中获取项目文件路径
本文转载自:http://blog.163.com/michaelgaoit%40126/blog/static/11389538620103711613620/ web 上运行 1:this.get ...