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

Source

这是第二遍码这个题的题解了,第一遍快打完的时候被我菊儿子手贱删掉了

题目要让两个集合中的所有数互质,那么就是相同的质因子不能位于两个不同的集合中

所以这个题的限制和突破口其实就是质因子

我们容易发现选了一个数就是相当与选了这个数的质因子的集合,所以我们需要对每个数进行质因数分解

但是500以内的质数还是比较多的,我们无法通过比较快捷有效的方法每个质因子是否出现过

然后我们就需要知道一个很鬼的东西:

在一个数的所有质因子中最多只有一个会大于sqrt(n);

证明:一个数可以被分解为几个质因子相乘,且这种分解是唯一的,如果有两个质数大于sqrt(n),那么乘积就会大于n,矛盾

那么sqrt(500)==22.36,在这里面的质数只有8个{2,3,5,7,9,11,13,17,19}.

这样一个数小于sqrt(n)的因子就可以用状态压缩来完美判断是否出现,我们还需要对大于sqrt的质因子特殊处理

用一个结构体来存储一个数

一是要记录这个数前8个因子的二进制状态:zt,二是记录大于等于sqrt(n)的因子 greatest是多少,如果没有则记为1

我们把数按照greatest排序那么我们可以把greatest相同的放在一起

我们易发现greatest相同且不为1的必须捆绑处理:必须是只放入第一个人或者只放入第二个人或者都不放入

我们讲到现在就可以设状态了

f[s1][s2]表示全局第一个人选集合s1,第二个人选集合s2的方案数(s1,s2都是表示一个二进制的状态);

g[0][s1][s2],g[1][s1][s2]是临时由f[s1][s2]赋值,再反过来更新f[s1][s2]

g[0][s1][s2]表示第一个人选s1,第二个人选s2,且当前这个数由第一个人选的方案

g[1][s1][s2]则反之

比如把一个数由第一个人选那么我们首先要判断a[i].zt&s2==0,即该数不会与第二个人的集合s2发生矛盾

我们易想到到转移方程

g[0][a[i].zt| s1][s2]+=g[0][s1][s2];

做一遍DP,直到完整的区间结束后由g[0][s1][s2],g[1][s1][s2]赋值给f[s1][s2],这样会保证这个区间的所有数的选择是一样的,不会分居两个集合

但由于都不选的算了两次,所以f[i][j]=g[0][s1][s2]+g[1][s1][s2]-f[s1][s2]

这个题要搞清楚f和g的转化时间,最后统计答案即可

这样就AC了

// MADE BY QT666
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<iostream>
#include<queue>
#include<set>
#include<cstdlib>
#include<cstring>
#include<string>
#include<ctime>
#define lson num<<1
#define rson num<<1|1
#define int long long
using namespace std;
const int MAXS=257;
const int N=550;
const int S=255;
int gi()
{
int x=0,flag=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') flag=-1;ch=getchar();}
while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
return x*flag;
}
struct data
{
int zt,greatest;
}a[N];
int n,mod,f[MAXS][MAXS],g[2][MAXS][MAXS];
int biao[10]={2,3,5,7,11,13,17,19};
void pre(){
for(int i=2;i<=n;i++) {
int x=i;
for(int j=0;j<8;j++) {
if(x%biao[j]>0) continue;
a[i].zt|=(1<<j);
while(x%biao[j]==0) x/=biao[j];
}
a[i].greatest=x;
}
}
bool cmp(data a,data b){
return a.greatest<b.greatest;
}
void work(){
for(int i=2;i<=n;i++){
if(i==2||a[i].greatest!=a[i-1].greatest||a[i].greatest==1){
memcpy(g[0],f,sizeof(f));
memcpy(g[1],f,sizeof(f));
}
for(int j=S;j>=0;j--)
for(int k=S;k>=0;k--){
if((j&k)==0){
if((a[i].zt&k)==0)
g[0][a[i].zt|j][k]+=g[0][j][k],g[0][a[i].zt|j][k]%=mod;
if((a[i].zt&j)==0)
g[1][j][a[i].zt|k]+=g[1][j][k],g[1][j][a[i].zt|k]%=mod;
}
}
if(n==2||a[i].greatest!=a[i+1].greatest||a[i].greatest==1){
for(int j=S;j>=0;j--)
for(int k=S;k>=0;k--){
if((j&k)==0){
f[j][k]=g[0][j][k]+g[1][j][k]-f[j][k];
}
}
}
}
}
main()
{
n=gi(),mod=gi();
pre();
sort(a+2,a+1+n,cmp);
f[0][0]=1;
work();
int ans=0;
for(int i=S;i>=0;i--)
for(int j=S;j>=0;j--)
if((i&j)==0)
ans+=f[i][j],ans%=mod;
while(ans<0) ans+=mod;ans%=mod;
printf("%lld",ans);
}

bzoj 4199 [NOI2015]寿司晚宴的更多相关文章

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

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

  2. BZOJ 4197: [Noi2015]寿司晚宴 状态压缩 + 01背包

    4197: [Noi2015]寿司晚宴 Time Limit: 10 Sec  Memory Limit: 512 MB Description 为了庆祝 NOI 的成功开幕,主办方为大家准备了一场寿 ...

  3. [BZOJ]4197: [Noi2015]寿司晚宴

    Time Limit: 10 Sec  Memory Limit: 512 MB Description 为了庆祝 NOI 的成功开幕,主办方为大家准备了一场寿司晚宴.小 G 和小 W 作为参加 NO ...

  4. bzoj 4197: [Noi2015]寿司晚宴【状压dp】

    一个数内可能多个的质因数只有小于根号n的,500内这样的数只有8个,所以考虑状压 把2~n的数处理出小于根号500的质因数集压成s,以及大质数p(没有就是1),然后按p排序 根据题目要求,拥有一个质因 ...

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

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

  6. [BZOJ4197][Noi2015]寿司晚宴

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

  7. BZOJ_4197_[Noi2015]寿司晚宴_状态压缩动态规划

    BZOJ_4197_[Noi2015]寿司晚宴_状态压缩动态规划 Description 为了庆祝 NOI 的成功开幕,主办方为大家准备了一场寿司晚宴.小 G 和小 W 作为参加 NOI 的选手,也被 ...

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

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

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

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

随机推荐

  1. sklearn 划分数据集。

    1.sklearn.model_selection.train_test_split随机划分训练集和测试集 函数原型: X_train,X_test, y_train, y_test =cross_v ...

  2. C#设计模式之十七观察者模式(Observer Pattern)【行为型】

    一.引言   今天是2017年11月份的最后一天,也就是2017年11月30日,利用今天再写一个模式,争取下个月(也就是12月份)把所有的模式写完,2018年,新的一年写一些新的东西.今天我们开始讲& ...

  3. (ajax)——jquery用法

    例子:/* ajax获得状态 */                点击事件  $("#findBycname").click(function(){  var company = ...

  4. margin、padding单位百分比

    年前做了一个测试题 https://www.wenjuan.com/s/VjaEva/,里面有一道题目涉及到了margin和padding单位为百分比的情况.写出来记录一下以防止自己忘记. <! ...

  5. 中介者模式(Mediator)

    中介者模式(Mediator) 中介者模式也是用来降低类类之间的耦合的,因为如果类类之间有依赖关系的话,不利于功能的拓展和维护,因为只要修改一个对象,其它关联的对象都得进行修改.如果使用中介者模式,只 ...

  6. php中使用swoole实现头协议

    当需要有数据交互的时候,为了安全起见,双方会协商一个固定的头协议,这样必须实现其头协议才能拿到数据. PHP的swoole完美的提供了固定包头+包体协议自动分包. 首先需要通过open_length_ ...

  7. Filter、Listener 学习总结

    今天我们来介绍 Filter.Listener 这两个模块一些简单的知识和应用,接下来我们开始我们的正题 ! 1. Filter(过滤器) 1.1 对 Servlet 容器调用 Servlet 的过程 ...

  8. 前端chrome浏览器调试

    引言 "工欲善其事,必先利其器" 恩,这句话我觉得说的特别有道理,举个例子来说吧,厉害的化妆师都有一套非常专业的刷子,散粉刷负责定妆,眼影刷负责打眼影,各司其职,有了专业的工具才能 ...

  9. 实战-Mysql5.6.36脚本编译安装及初始化

    概述 本文为centos7.3自动化编译安装mysql5.3.6的脚本及后续初始化操作,话不多少,直接上脚本. 安装脚本install.py如下: #coding=utf-8 #!/usr/bin/p ...

  10. Qwt安装(转)

    ======= 安装 ======= Qwt使用qmake编译所有的组件和示例. qmake是Qt发布中的一部分. qmake读取工程文件,工程文件包含了如何工程选项和如何编译特定工程的规则.一个工程 ...