N - 寿司晚宴 HYSBZ - 4197 状压dp
N - 寿司晚宴
这个题目我觉得还是很难的,借助题解写出来的,题解还看了很久,现在还是不是很理解。
首先这个数比较大有500,如果直接就像这个题目S - Query on a tree 这样写就超时了,而且也存不下这么大的数。
因为这个500以内的质数太多了,然后看了这么多题解你会发现根号500以内的质数只有8个。
而每一个数大于根号500的质数最多一个,所以我们可以先讨论这个小于根号500的质数,然后再判断这个大于根号500的质数。
讨论完之后再判断这个大于根号500的质数的问题。
然后发现这个题目可以一起计算这两个。
首先把这个按照大于根号500的这个数进行分块,大于根号500的相同的质数分成一块,只有每一个块的结束才可以更新答案。
这个是因为每一块里面我们第一个人选这个或者第二个人选这个,所以如果你每次都去更新答案就不可以保证只有一个人选择这块的这个质数。
其实本来只要一个f数字f[i][j]表示第一个人的状态为 i 第二个人的状态为 j 的方案数,但是因为我们要保证这一块只有一个人选了这个质数,
意思就是第一个人如果要选这个只能向他选了这个的方向转移,第二个人同理。
怎么确定这个转移方向就是加一维 g[k][i][j] k==0 代表第一个人选了,k==1 代表第二个人选的。
然后之后又不需要分开了,所以又赋值会 f 数组。
差不多就是这样。
总的来说:
1. 既然已知这个是一个状压dp就要去找状压什么,这个和质数有关,所以很明显就是状压质数,根据质因数分解所以可以知道每一个数大于根号x的数最多就一个。
2.状态转移,因为之前写过的那个题目,所以可以知道,首先枚举数,然后枚举状态,这个可以一起枚举这两个人的状态。
3.第二点是不考虑有大于根号500的质数的情况,对于大于根号500 这个需要一个新数组来转移,最后赋值回去。
这个赋值回去之后就表示之后的一个数可以任意选之前的两个状态之间的一个状态,没有冲突。
对于第三点可以这么说,就是在每一块里面我们进行转移,分块的结束我们在重新赋值,之后又分块,但是后面的块可以向前面块中转移。
讲的也不是很清楚,感觉自己还是不是很理解。
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
#define inf 0x3f3f3f3f
#define inf64 0x3f3f3f3f3f3f3f3f
using namespace std;
const int maxn = 1e5 + ;
typedef long long ll;
ll dp[ << ][ << ], g[][ << ][ << ];
struct node {
ll s, prime;
}a[maxn];
int p[maxn], isp[maxn], m;
void init() {
for (int i = ; i < ; i++) p[i] = ;
for (int i = ; i*i < ; i++) {
if (p[i]) {
for (int j = i * i; j <= ; j += i) {
p[j] = ;
}
}
}
int m = ;
for (int i = ; i <= maxn; i++) if (p[i]) isp[m++] = i;
}
bool cmp(node a, node b) {
return a.prime < b.prime;
}
int main() {
init();
int n, mod;
scanf("%d%d", &n, &mod);
for (int i = ; i < n; i++) {
int x = i + ;
for (int j = ; j < ; j++) {
if (x%isp[j]) continue;
a[i].s |= ( << j);
while (x%isp[j] == ) x /= isp[j];
}
a[i].prime = x;
}
int ends = ( << );
memset(dp, , sizeof(dp));
dp[][] = ;
sort(a + , a + n, cmp);
for (int i = ; i < n; i++) {
if (i == || a[i].prime != a[i - ].prime || a[i].prime == ) {
memcpy(g[], dp, sizeof(dp));
memcpy(g[], dp, sizeof(dp));
}
for (int j = ends - ; j >= ; j--) {
for (int k = ends - ; k >= ; k--) {
if (j&k) continue;
if ((a[i].s&k) == ) (g[][a[i].s | j][k] += g[][j][k]) %= mod;
if ((a[i].s&j) == ) (g[][j][k | a[i].s] += g[][j][k]) %= mod;
}
}
if (i == n - || a[i].prime != a[i + ].prime || a[i].prime == ) {
for (int j = ends - ; j >= ; j--) {
for (int k = ends - ; k >= ; k--) {
if (j&k) continue;
dp[j][k] = (g[][j][k] + g[][j][k] - dp[j][k] + mod) % mod;
}
}
}
}
ll ans = ;
for (int j = ends - ; j >= ; j--) {
for (int k = ends - ; k >= ; k--) {
if (j&k) continue;
ans += dp[j][k];
ans %= mod;
}
}
ans += mod;
printf("%lld\n", ans%mod);
return ;
}
状压 难
N - 寿司晚宴 HYSBZ - 4197 状压dp的更多相关文章
- UOJ129 NOI2015 寿司晚宴 数论、状压DP
传送门 数论题\(n \leq 500\)肯定是什么暴力算法-- 注意到每一个数\(> \sqrt{n}\)的因子最多只有一个,这意味着\(> \sqrt{n}\)的因子之间是独立的,而只 ...
- 【NOI2015】【寿司晚宴】【状压DP】
Description 为了庆祝 NOI 的成功开幕,主办方为大家准备了一场寿司晚宴. 小 G 和小 W 作为參加 NOI 的选手,也被邀请參加了寿司晚宴. 在晚宴上,主办方为大家提供了 n−1 种不 ...
- UOJ #129 / BZOJ 4197 / 洛谷 P2150 - [NOI2015]寿司晚宴 (状压dp+数论+容斥)
题面传送门 题意: 你有一个集合 \(S={2,3,\dots,n}\) 你要选择两个集合 \(A\) 和 \(B\),满足: \(A \subseteq S\),\(B \subseteq S\), ...
- NOI 2015 寿司晚宴 (状压DP+分组背包)
题目大意:两个人从2~n中随意取几个数(不取也算作一种方案),被一个人取过的数不能被另一个人再取.两个人合法的取法是,其中一个人取的任何数必须与另一个人取的每一个数都互质,求所有合法的方案数 (数据范 ...
- 排列perm HYSBZ - 1072(状压dp/暴力)
Description 给一个数字串s和正整数d, 统计s有多少种不同的排列能被d整除(可以有前导0).例如123434有90种排列能被2整除,其中末位为2的有30种,末位为4的有60种. Input ...
- 【bzoj4197】[Noi2015]寿司晚宴 分解质因数+状态压缩dp
题目描述 为了庆祝 NOI 的成功开幕,主办方为大家准备了一场寿司晚宴.小 G 和小 W 作为参加 NOI 的选手,也被邀请参加了寿司晚宴. 在晚宴上,主办方为大家提供了 n−1 种不同的寿司,编号 ...
- 状压DP复习
深感自己姿势水平之蒻……一直都不是很会状压DP,NOIP又特别喜欢考,就来复习一发…… 题目来源 Orz sqzmz T1 [BZOJ4197][NOI2015]寿司晚宴 (做过)质因数分解最大的质因 ...
- 状压DP之LGTB 与序列
题目 思路 这道题竟然是状压DP,本人以为是数论,看都没看就去打下一题的暴力了,哭 \(A_i\)<=30,所以我们只需要考虑1-58个数,再往后选的话还不如选1更优,注意,1是可以重复选取的, ...
- K - Painful Bases 状压dp
Painful Bases LightOJ - 1021 这个题目一开始看,感觉有点像数位dp,但是因为是最多有16进制,因为限制了每一个数字都不同最多就有16个数. 所以可以用状压dp,看网上题解是 ...
随机推荐
- 通过bat文件 进行mysql 连接 或者 操作涉及 密码的,如果密码 中有 % 号的话要特殊处理
比如我想在bat文件中进行一个数据库的连接 或者进行一个数据库中的 数据 导入或者导出(mysqldump) 这样子都会用到数据库密码, 假如这个数据库的密码 中又有 % 的话就要特殊转义一下才行执行 ...
- 绕过CDN查找真实 IP 姿势总结
返回域名解析对应多个 IP 地址,网站可能部署CDN业务,我们就需要bypass CDN,去查找真正的服务器ip地址 0x01.域名搜集 由于成本问题,可能某些厂商并不会将所有的子域名都部署 CDN, ...
- Threejs【坐标转换】如何让annotation跟随物体一起旋转
现在根据鼠标点击的屏幕位置能够得到屏幕的坐标event.clientX和event.clientY,然后我的annotation就初始化在这个屏幕坐标的位置,那么如何绑定annotation和三维物体 ...
- 空间小姐姐生活照,我用python破解加密压缩包,无忧查看
事情的经过是这样的: 又是奶茶,行吧行吧. 快点开工,争取李大伟回来之前搞定. 李大伟说是6位数字密码 那么我们可以利用python生成全部的六位数字密码 #生成从000000到99999的密码表f ...
- linux下的信号量PV操作进阶之路
一.同步和互斥机制 信号量 互斥锁 同步:指多个任务按照约定的先后次序相互配合来完成一件事情. 比如读线程等待写线程写完之后再去读. 二.信号量-P/V操作 P(s)含义: if(信号量>0) ...
- Flutter环境安装,ios真机调试
MAC: 下载Flutter,官网的可能很慢.可以去我的网盘下载, 提取码: 3t6y. 下载完的包会在~/Downloads目录下,我们移到~/opt/flutter目录下. mkdir ./opt ...
- PHP代码审计理解(一)----Metinfo5.0变量覆盖
0x01 漏洞简介 这个漏洞是metinfo5.0变量覆盖漏洞,并且需要结合文件包含.我使用的cms版本是5.3,事实上已经修复了这个漏洞(5.0的cms源码已经找不到了哈),但是我们可以借他来学习理 ...
- 存储-raid
- Cannot find libcrypto in Ubuntu
https://stackoverflow.com/questions/13811889/cannot-find-libcrypto-in-ubuntu sudo apt-get install li ...
- 增量学习不只有finetune,三星AI提出增量式少样本目标检测算法ONCE | CVPR 2020
论文提出增量式少样本目标检测算法ONCE,与主流的少样本目标检测算法不太一样,目前很多性能高的方法大都基于比对的方式进行有目标的检测,并且需要大量的数据进行模型训练再应用到新类中,要检测所有的类别则需 ...