题目链接

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. XAF.web.NewUI:如何自定义主题

    一.使用主题制作工具导出主题: 修改主题生成器工具导出的主题.改完后,导出到 App_Themes 文件夹.例如,更改 ASPxGridView 组面板和Pager面板背景色并保存更改. 使用Them ...

  2. css布局笔记(一)

    布局方式 一列布局 通常固定宽高,用margin:0 auto:居中显示 两列布局 说起两列布局,最常见的就是使用float来实现.float浮动布局的缺点是浮动后会造成文本环绕等效果,以及需要及时清 ...

  3. 一个IP可以登几个拼多多后台 拼多多如何推广营销

    想要在拼多多上开双店?担心一根网线会引起IP冲突?那么一根网线可以登几个拼多多后台呢?有数据显示,挂双店是没有问题的,甚至可以多开.那么解决了一根网线的事情,要怎么对自己的店铺进行营销推广呢?下面是小 ...

  4. appium -- 页面出现弹窗,关闭后,无法识别页面元素(转)

    原文:https://www.cnblogs.com/leavescy/p/9733001.html; 1. 问题:如图所示:在修改手势密码的过程中,点击了返回按钮后,弹出该弹窗:点击继续设置后,就发 ...

  5. Jenkins Git安装设置

    Jenkins Git安装设置 在此安装中,必须确保Internet连接可连接其安装 Jenkins 机器.在 Jenkins 仪表盘(主屏幕)的左侧单击 Manage Jenkins 选项.打开网址 ...

  6. cinder的组件

    跟nova相似,cinder也有很多组件,每个组件负责各自的业务,然后共同协作完成volume的管理.组件之间的通信方式与nova个组件之间的通信方式相同,都是通过消息队列进行通信. cinder-a ...

  7. Could not resolve placeholder 'jdbc.url' in value "${jdbc.url}"

    写完接口之后,发现报了这个错误,查了一下发现,spring不允许使用两个 <context:property-placeholder>

  8. C++ 名字空间namespace的使用

    A namespace is a scope.C++ provides namespaces to prevent name conflicts.A namespace is a mechanism ...

  9. 欢迎来怼---作业要求 20171015 beta冲刺贡献分分配规则

    一.小组信息 队名:欢迎来怼 小组成员 队长:田继平 成员:李圆圆,葛美义,王伟东,姜珊,邵朔,阚博文 基础分      每人占个人总分的百分之40% leangoo里面的得分    每人占个人总分里 ...

  10. python 二维矩阵及转byte知识点

    1.注意python中的数组和list形式混合: 数组在numpy里面: 2.二维数组这样定义可以修改固定位置的值: rawDataArray_temp = [([0]*nIRImageWidth)f ...