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
题解:能够发现,选了一个数等于是选了它的质因子。首先n仅仅有500,所以小于根号500的质因子仅仅有8个。

我们能够把这8个质因子压成二进制位。形成2^8个集合。

对于每一个数。仅仅可能含有不超过1个大于根号500的质因子,我们按这个将每一个数分类。

把每一个数存到一个结构体s里,s.kind表示这个数里大于根号500的质因子是什么。没有的话为1。s.se表示这个数小于根号500的质因子的包括情况,用二进制位压一下。

然后我们按kind排序。dp就可以。
dp的时候把kind同样的放在一起dp。

设f[i][j]表示第一个人选了i这个质因数集合,第二个人选了j这个质因数集合的方案数。
对于每一类数開始dp时。

先把f数组复制两遍到p[1]和p[2];

p[i][j][k]表示当前是第i个人进行操作。第1个人选的集合是j第二个人是k的方案数。
用p数组进行更新。

dp结束后要用p数组更新f数组。f=p1+p2-f; 由于两个p数组中都包括了选当前数的情况,然而这显然是不能够的,所以要减去之前的f。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int f[301][301],p[3][301][301],pp,ans;
int prime[8]={2,3,5,7,11,13,17,19},n;
struct use{
int kind,se;
}s[600];
bool cmp(use a,use b)
{
if (a.kind!=b.kind) return a.kind<b.kind;
else return a.se<b.se;
}
int main()
{
freopen("dinner.in","r",stdin);
freopen("dinner.out","w",stdout);
scanf("%d%d",&n,&pp);
for (int i=1;i<=n;i++)
{
int temp;
temp=i;
for (int j=0;j<8;j++)
if (temp%prime[j]==0)
{
s[i].se|=1<<j;
while (temp%prime[j]==0) temp/=prime[j];
}
s[i].kind=temp;
}
sort(s+2,s+n+1,cmp);
f[0][0]=1;
for (int i=2;i<=n;i++)
{
if (i==2||s[i].kind==1||s[i].kind!=s[i-1].kind)
{
memcpy(p[1],f,sizeof f );
memcpy(p[2],f,sizeof f );
}
for (int j=255;j>=0;j--)
for (int k=255;k>=0;k--)
{
if ((k&s[i].se)==0) p[1][j|s[i].se][k]=(p[1][j|s[i].se][k]+p[1][j][k])%pp;
if ((j&s[i].se)==0) p[2][j][k|s[i].se]=(p[2][j][k|s[i].se]+p[2][j][k])%pp;
}
if (i==n||s[i].kind==1||s[i].kind!=s[i+1].kind)
{
for (int j=0;j<=255;j++)
for (int k=0;k<=255;k++)
f[j][k]=((p[1][j][k]+p[2][j][k]-f[j][k])%pp+pp)%pp;
}
}
ans=0;
for (int i=0;i<=255;i++)
for (int j=0;j<=255;j++)
if ((i&j)==0) ans=(ans+f[i][j])%pp;
cout<<ans<<endl;
}

【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. BZOJ 4197: [Noi2015]寿司晚宴 状压dp+质因数分解

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. 在windows 10 64bit系统上安装python 3.6 64bit的numpy模块

    1.查找自己的python版本对照的whl文件(cp36代表的是版本) 地址:https://pypi.python.org/pypi/numpy 2.下载完毕执行一下命令即可 pip install ...

  2. codeforces-540C

    题目连接:http://codeforces.com/problemset/problem/540/C C. Ice Cave time limit per test 2 seconds memory ...

  3. CF978A Remove Duplicates【数组操作/STL】

    [链接]:CF978A [分析]:逆向思考+标记数组去重 [代码]: #include<bits/stdc++.h> using namespace std; const int INF ...

  4. Java里如何判断一个String是空字符串或空格组成的字符串

      要判读String是否为空字符串,比较简单,只要判断该String的length是否为0就可以,或者直接用方法isEmpty()来判断. 但很多时候我们也会把由一些不可见的字符组成的String也 ...

  5. js日常笔记

    写在前面: 在工作中,有时候会遇到一些零零碎碎的小知识点,虽然这些网上都可以查询到,但还是想把一些自己不是很熟悉的当做笔记记录下来,方便以后查询. 1.按钮隐藏/显示/可用/不可用 $("# ...

  6. 使用Windows Live Writer开始发布cnblogs日志的方法

    1.下载Windows Live Writer http://www.microsoft.com/zh-cn/download/confirmation.aspx?id=8621 2.安装Window ...

  7. Visual Studio 插件开发资源

    微软官方MSDN 官方MSDN永远是最大而全的电子字典Visual Studio Software Development Kit ,不过它的资料虽然详细,但没有一定的基础的话直接使用它的话有点无从入 ...

  8. github 多账户配置

    一直以来git都是自己业余玩玩,虽然也在github上有个账户,也只是小打小闹,弄了若干个测试仓库.最近公司要从TFS迁移到Gerrit,也算是正式用git了.不过遇到的一个问题就是账户问题,一个个人 ...

  9. VBA Collection用法总结

    Sub test() ' Dim s As Collection '定义s变量为集合对象 ' Set s = New Collection '初始化集合对象s (否则无法使用) Dim s As Ne ...

  10. Ext JS 5 gpl版本 官方原版的下载方法

    先进入官网: 然后在导航的Products中选择Sencha Ext JS,会看到以下页面: 这时候不要单击Download按钮,而是要单击导航中的DETAILS,页面切换后,就可在底部看到GPL版本 ...