题目链接

BZOJ4197

题解

两个人选的数都互质,意味着两个人选择了没有交集的质因子集合

容易想到将两个人所选的质因子集合作为状态\(dp\)

\(n\)以内质数很多,但容易发现\(\sqrt{n} \approx 22.3\),这里边的质数只有\(8\)个,而大于\(\sqrt{n}\)的质因子只会出现一次,可以特殊讨论

我们先将所有数按最大质因子排序,如果最大质因子在那\(8\)个质数里边,就记为\(1\)

我们设\(f[i][s1][s2]\)表示选了前\(i\)个数,两人的质因子集合分别为\(s1\)和\(s2\)的方案数

那么显然

\[ans = \sum\limits_{s1 \cap s2 = \emptyset} f[n][s1][s2]
\]

对于最大质因子不超过\(sqrt{n}\)的那些数,我们可以枚举加入\(s1\)或\(s2\)进行转移

对于同一组最大质因数为\(x\)的数,我们先将\(f\)拷贝到\(g\)中,令\(g[0|1][i][s1][s2]\)表示该最大质因数加入谁中,选了前\(i\)个数,质因子集合为\(s1\),\(s2\)的方案数

求完后令\(f[i][s1][s2] = g[0][i][s1][s2] + g[1][i][s1][s2] - f[i][s1][s2]\),因为原来的\(f\)是不包含这一组数的方案,而两个\(g\)都包含了不包含这一组数的方案数,要减去一个

由于空间问题,\(f\)和\(g\)都要通过逆序转移压掉\(i\)那一维

然后就做完了

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<map>
#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define mp(a,b) make_pair<int,int>(a,b)
#define cls(s) memset(s,0,sizeof(s))
#define cp pair<int,int>
#define LL long long int
using namespace std;
const int maxn = 505,maxm = 1 << 8,INF = 1000000000;
inline int read(){
int out = 0,flag = 1; char c = getchar();
while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();}
while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();}
return out * flag;
}
int f[maxm][maxm],g[2][maxm][maxm];
int n,P,a[maxn];
int p[] = {2,3,5,7,11,13,17,19};
struct node{
int x,p;
}e[maxn];
inline bool operator <(const node& a,const node& b){
return a.p < b.p;
}
int getp(int x){
for (int i = 0; i < 8; i++)
if (x % p[i] == 0) while (x % p[i] == 0) x /= p[i];
return x;
}
void init(){
for (int i = 2; i <= n; i++)
for (int k = 0; k < 8; k++)
if (i % p[k] == 0)
a[i] |= (1 << k);
}
int main(){
n = read(); P = read(); init();
for (int i = 2; i <= n; i++) e[i].x = i,e[i].p = getp(i);
sort(e + 2,e + 1 + n);
f[0][0] = 1;
for (int i = 2; i <= n; i++){
int x = e[i].x,s = a[x];
if (e[i].p == 1){
for (int j = maxm - 1; ~j; j--){
for (int k = maxm - 1; ~k; k--){
int t = f[j][k];
f[j][k | s] = (f[j][k | s] + t) % P;
f[j | s][k] = (f[j | s][k] + t) % P;
}
}
}
else {
for (int j = 0; j < maxm; j++)
for (int k = 0; k < maxm; k++)
g[0][j][k] = g[1][j][k] = f[j][k];
int nxt = i;
while (nxt < n && e[nxt + 1].p == e[i].p) nxt++;
for (int l = 0; l <= nxt - i; l++){
x = e[l + i].x,s = a[x];
for (int j = maxm - 1; ~j; j--){
for (int k = maxm - 1; ~k; k--){
g[0][j | s][k] = (g[0][j | s][k] + g[0][j][k]) % P;
g[1][j][k | s] = (g[1][j][k | s] + g[1][j][k]) % P;
}
}
}
i = nxt;
for (int j = 0; j < maxm; j++)
for (int k = 0; k < maxm; k++)
f[j][k] = (((g[1][j][k] + g[0][j][k]) % P - f[j][k]) % P + P) % P;
}
}
int ans = 0;
for (int j = 0; j < maxm; j++)
for (int k = 0; k < maxm; k++)
if (!(j & k)) ans = (ans + f[j][k]) % P;
printf("%d\n",ans);
return 0;
}

BZOJ4197 [Noi2015]寿司晚宴 【状压dp】的更多相关文章

  1. bzoj4197 [Noi2015]寿司晚宴——状压DP

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4197 首先,两个人选的数都互质可以看作是一个人选了一个数,就相当于选了一个质因数集合,另一个 ...

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

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

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

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

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

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

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

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

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

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

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

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

  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. javaweb(二十九)——EL表达式

    一.EL表达式简介 EL 全名为Expression Language.EL主要作用: 1.获取数据 EL表达式主要用于替换JSP页面中的脚本表达式,以从各种类型的web域 中检索java对象.获取数 ...

  2. 基于Cocos2d-x-1.0.1的飞机大战游戏开发实例(上)

    最近接触过几个版本的cocos2dx,决定每个大变动的版本都尝试一下.本实例模仿微信5.0版本中的飞机大战游戏,如图: 一.工具 1.素材:飞机大战的素材(图片.声音等)来自于网络 2.引擎:coco ...

  3. python--自定义模块

    python模块说明:类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代码的重用性和代码间的耦合.而对于一个复杂的功能来,可能需要多个函数才能完成(函数又可以在不 ...

  4. 《图解 HTTP 》阅读 —— 第三章

    第3章 HTTP 报文内的 HTTP 信息 用于 HTTP 协议交互的信息称为 HTTP 报文:请求报文和响应报文 HTTP 在传输数据时通过编码可以提升速率,能有效的处理大量数据,但是会消耗更多的C ...

  5. 微信小程序转换为百度小程序

    据粗略预估,微信小程序和百度小程序,有至少90%以上的相似代码,而且api的参数和返回的数据都是一致的,有一些不一致的将做如下介绍:.wxml文件,改成后辍名.swan.wxss文件,改成后辍名为.c ...

  6. Select 、Poll 和 Epoll

    作用 Epoll 和 Select 的作用都是为了多I/O同步复用的问题,利用Epoll.Poll或Select函数指定内核监听多个I/O的读.写.异常事件,避免每一个I/O都指定一个处理线程,导致开 ...

  7. Apriori 获取关联规则实现

    前言 自己的一个Apriori 获取关联规则的python实现.具体原理不讲,代码添加了说明,还是很好理解的. 数据预处理 #最小置信度 min_conf = 0.5 #最小支持度 min_sup = ...

  8. ASP.NET 异步Web API + jQuery Ajax 文件上传代码小析

    该示例中实际上应用了 jquery ajax(web client) + async web api 双异步. jquery ajax post $.ajax({ type: "POST&q ...

  9. hive 2以上版本启动异常 Unable to instantiate org.apache.hadoop.hive.ql.metadata.SessionHiveMetaStoreClient

    hive2.0以上的版本启动时 抛出 “Unable to instantiate org.apache.hadoop.hive.ql.metadata.SessionHiveMetaStoreCli ...

  10. Python:字符串中引用外部变量的3种方法

    方法一: username=input('username:') age=input('age:') job=input('job:') salary=input('salary') info1='' ...