P2150 [NOI2015] 寿司晚宴

刚开始看错题了,推了一个与原题类似的 DP 方程,然后不会优化,笑了。

思路

首先看到 \(n\) 很小,然后质因子个数就更少了。

因此第一反应是将所有的质因子状压进一个状态里,然后互相判断有没有互质即可。

但是 500 以内的质因子个数并不少,有接近 100 个,因此这只是 30 分的暴力。

但是有一个比较常见的优化:每个数只会有一个大于 \(\sqrt n\) 的质因子。因此我们将这种因子称为“大质因子”。

我们预处理出每个数的大质因子是多少,将所有大质因子相同的数一起转移。

与暴力类似的,我们设 \(f1_{s1,s2},f2_{s1,s2}\) 分别表示所有大质因子相同的数只能第一个人选或不选的方案数,只能第二个人选或不选的方案数。(因为两个人不能同时选有相同大质因子相同的数)

注意,这里的 \(s1,s2\) 只压缩了“小质因子”。

然后假设当前枚举到第 \(i\) 个数,其所有小质因子的压缩为 \(s_i\),有转移

\[\begin{aligned}
f1_{s1 \cup s_i,s2} \gets f1_{s1 \cup s_i,s2}+f1_{s1,s2},s2\cap s_i=\varnothing \\
f1_{s1 ,s2\cup s_i} \gets f1_{s1 ,s2\cup s_i}+f1_{s1,s2},s1\cap s_i=\varnothing
\end{aligned}
\]

然后设 \(dp_{s1,s2}\) 在大质因子不同的阶段间转移。每次一个阶段时将 \(dp\) 复制进 \(f1,f2\) 中,结束时用 \(f1,f2\) 更新 \(dp\) 即可。具体而言,结束时有

\[dp_{s1,s2}\gets f1_{s1,s2}+f2_{s1,s2}-dp_{s1,s2}
\]

减掉一个 \(dp\) 是为了减掉重复的情况。答案就是 \(dp\) 的和。

code

注意可能有数没有质因子大于 \(\sqrt n\)。发现这个时候其质因子个数必定小于等于 \(8\),因此直接在 \(dp\) 数组上用暴力做即可。

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=505;
int n,p,pri[N]={2,3,5,7,11,13,17,19},dp[N][N],f1[N][N],f2[N][N];
struct node{int s,mp;}a[N];
bool cmp(node x,node y){return x.mp<y.mp;}
void add(int &x,int y){x=(x+y+p)%p;}
signed main(){
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
cin>>n>>p;
for(int i=2;i<=n;i++){
int tmp=i;
for(int j=0;j<8;j++){
while(tmp%pri[j]==0) tmp/=pri[j],a[i].s|=(1<<j);
}
a[i].mp=tmp;
}
sort(a+2,a+n+1,cmp);int tl=2,tr=2;dp[0][0]=1;
while(a[tr+1].mp==1) tr++;
for(int i=tl;i<=tr;i++){
for(int s1=255;s1>=0;s1--) for(int s2=255;s2>=0;s2--){
if((s2&a[i].s)==0) add(dp[s1|a[i].s][s2],dp[s1][s2]);
if((s1&a[i].s)==0) add(dp[s1][s2|a[i].s],dp[s1][s2]);
}
}
for(int l=tr+1,r;l<=n;){
r=l;while(a[r].mp==a[r+1].mp) r++;
for(int s1=255;s1>=0;s1--) for(int s2=255;s2>=0;s2--) f1[s1][s2]=dp[s1][s2],f2[s1][s2]=dp[s1][s2];
for(int i=l;i<=r;i++)for(int s1=255;s1>=0;s1--) for(int s2=255;s2>=0;s2--){
if((s2&a[i].s)==0) add(f1[s1|a[i].s][s2],f1[s1][s2]);
if((s1&a[i].s)==0) add(f2[s1][s2|a[i].s],f2[s1][s2]);
}
for(int s1=255;s1>=0;s1--) for(int s2=255;s2>=0;s2--) (dp[s1][s2]=f1[s1][s2]+f2[s1][s2]-dp[s1][s2]+p)%=p;
l=r+1;
}
int ans=0;
for(int s1=255;s1>=0;s1--) for(int s2=255;s2>=0;s2--) (ans+=dp[s1][s2])%=p;
cout<<ans<<'\n';return 0;
}

P2150 [NOI2015] 寿司晚宴 题解的更多相关文章

  1. BZO4197 & 洛谷2150 & UOJ129:[NOI2015]寿司晚宴——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=4197 https://www.luogu.org/problemnew/show/P2150 ht ...

  2. UOJ #129 / BZOJ 4197 / 洛谷 P2150 - [NOI2015]寿司晚宴 (状压dp+数论+容斥)

    题面传送门 题意: 你有一个集合 \(S={2,3,\dots,n}\) 你要选择两个集合 \(A\) 和 \(B\),满足: \(A \subseteq S\),\(B \subseteq S\), ...

  3. 并不对劲的bzoj4197:loj2131:uoj129:p2150:[NOI2015]寿司晚宴

    题目大意 有两个集合\(S_1,S_2 \subseteq [2,n] (n\leq 500)\),且对于\(\forall x\in S_1,y\in S_2 , gcd(x,y)=1\) 求\(S ...

  4. 洛谷$P2150\ [NOI2015]$寿司晚宴 $dp$

    正解:$dp$ 解题报告: 传送门$QwQ$. 遇事不决写$dp$($bushi$.讲道理这题一看就感觉除了$dp$也没啥很好的算法能做了,于是考虑$dp$呗 先看部分分?$30pts$发现质因数个数 ...

  5. p2150 [NOI2015]寿司晚宴

    传送门 分析 我们发现对于大于$\sqrt(n)$的数每个数最多只会包含一个 所以我们把每个数按照大质数的大小从小到大排序 我们知道对于一种大质数只能被同一个人取 所以f1表示被A取,f2表示被B取 ...

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

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

  7. [UOJ#129][BZOJ4197][Noi2015]寿司晚宴

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

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

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

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

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

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

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

随机推荐

  1. kali linux脚本小子速成

    $如果你耐心看十分钟,你会惊奇的发现我讲的是一堆废话,别急.kali linux博大精深,绝对不是十分钟就能学的完,真正的好东西永远都是夹在屎里,想学你想要的,拿出你的决心来. kali linux用 ...

  2. [ARC148C] Lights Out on Tree 题解

    在考场遇到了这道题,感觉很有意思. 当时直接想到的就是虚树,可惜打挂了. 后来改对了,写篇题解纪念一下. 首先看到 \(\sum M_i\le 2\times 10^5\),很容易想到虚树的数据范围. ...

  3. spring-boot配置slf4j日志

    SLF4J,即简单日志门面(Simple Logging Facade for Java),不是具体的日志解决方案,它只服务于各种各样的日志系统.按照官方的说法,SLF4J 是一个用于日志系统的简单 ...

  4. Typecho博客添加音乐外链支持Https

    首先选个音质和音乐比较全面的音乐站,这里选了网易云音乐,自己手机用的网易云音乐app,存了好多歌单,所以就选他了,但是想获取音乐文件链接,得去这儿:季春二九音乐站 其实很简单,参考下面. 1.先找到网 ...

  5. 刷入Magisk错误:1教程

    面具是目前使用最多的授权APP了,兼容主流安卓版本,基本上已彻底的替代的之前的supersu授权,面具magisk不仅支持给APP进行授权ROOT,还支持隐藏root功能magiskhide,使得手机 ...

  6. vue - [02] 安装部署

    Vue.js 是一个流行的前端JavaScript框架,用于构建用户界面. 001 || 通过CND快速开始 只需要在HTML文件中引入VUE的CDN链接即可 (1)创建HTML文件 <!DOC ...

  7. day1-简介与下载

    为什么创造了golang? 计算机硬件技术更新频繁,不能合理运用多核多CPU的的优势 目前市场缺乏一款简洁高效的编程语言 c++.c运行速度很快,但存在内存泄漏的问题 go语言特点 既做到了静态语言的 ...

  8. 【ABAQUS脚本】后处理快速出图

    效果图: # -*- coding: utf-8 -*- # Do not delete the following import lines from abaqus import * from ab ...

  9. 全面的C#/.NET/.NET Core面试宝典(永久免费)

    前言 C#/.NET/.NET Core相关技术常见面试题汇总,不仅仅为了面试而学习,更多的是查漏补缺.扩充知识面和大家共同学习.携手进步. 该知识库主要由自己平时学习和工作实践总结.网上优秀文章资料 ...

  10. 【P5】Verilog搭建流水线MIPS-CPU

    课下 Thinking_Log 1.为何不允许直接转发功能部件的输出 直接转发会使一些组合逻辑部件增加新的长短不一的操作延迟,不利于计算设置流水线是时钟频率(保证流水线吞吐量?). 2.jal中将NP ...