BZOJ4197 [Noi2015]寿司晚宴 【状压dp】
题目链接
题解
两个人选的数都互质,意味着两个人选择了没有交集的质因子集合
容易想到将两个人所选的质因子集合作为状态\(dp\)
\(n\)以内质数很多,但容易发现\(\sqrt{n} \approx 22.3\),这里边的质数只有\(8\)个,而大于\(\sqrt{n}\)的质因子只会出现一次,可以特殊讨论
我们先将所有数按最大质因子排序,如果最大质因子在那\(8\)个质数里边,就记为\(1\)
我们设\(f[i][s1][s2]\)表示选了前\(i\)个数,两人的质因子集合分别为\(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】的更多相关文章
- bzoj4197 [Noi2015]寿司晚宴——状压DP
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4197 首先,两个人选的数都互质可以看作是一个人选了一个数,就相当于选了一个质因数集合,另一个 ...
- 【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 ...
随机推荐
- 【转】bash: ssh: command not found解决方法(linux)
原文转自:http://www.cnblogs.com/ahauzyy/archive/2013/04/25/3043699.html 今天在搭建hadoop的开发环境中,用的是centsos6.0的 ...
- Mac 必备工具之 brew
brew 是 Mac 下的一个包管理工具,类似于 centos 下的 yum,可以很方便地进行安装/卸载/更新各种软件包,例如:nodejs, elasticsearch, kibana, mysql ...
- Struts 2(五):输入校验 & 校验框架
第一节 Struts2输入校验 1.1 输入校验的重要性 输入校验分为客户端校验和服务器端校验.客户端校验用来过滤用户的错误操作,一般使用JavaScript代码实现.服务器端校验用来防止非法用户的恶 ...
- web存储机制(localStorage和sessionStorage)
web存储包括两种:sessionStorage 和 localStorage(都是限定在文档源级别,非同源文档间无法共享) 1.sessionStorage 数据放在服务器上(IE不支持) 严格用于 ...
- python编码和小数据池
python_day_6 一. 回顾上周所有内容一. python基础 Python是一门解释型. 弱类型语言 print("内容", "内容", end=&q ...
- 从源码角度彻底理解ReentrantLock(重入锁)
目录 1.前言 2.AbstractQueuedSynchronizer介绍 2.1 AQS是构建同步组件的基础 2.2 AQS的内部结构(ReentrantLock的语境下) 3 非公平模式加锁流程 ...
- PHP性能优化 -实战篇
借助xhprof 工具分析PHP性能 XHPorf(源自Fackbook 的PHP性能分析工具) 实战 通过分析Wordpress程序,做优化! 优化 找到需要优化的函数 grep 'impo ...
- 基于腾讯云CLB实现K8S v1.10.1集群高可用+负载均衡
概述: 最近对K8S非常感兴趣,同时对容器的管理等方面非常出色,是一款非常开源,强大的容器管理方案,最后经过1个月的本地实验,最终决定在腾讯云平台搭建属于我们的K8S集群管理平台~ 采购之后已经在本地 ...
- List<T>.Distinct()
) }; //使用匿名方法 List<Person> delegateList = personList.Distinct(new Compar ...
- JS加密库
作者声明:本博客中所写的文章,都是博主自学过程的笔记,参考了很多的学习资料,学习资料和笔记会注明出处,所有的内容都以交流学习为主.有不正确的地方,欢迎批评指正 本文主要是参考aicoder马伦老师的博 ...