BZOJ4197 / UOJ129 [Noi2015]寿司晚宴
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作。
本文作者:ljh2000
作者博客:http://www.cnblogs.com/ljh2000-jump/
转载请注明出处,侵权必究,保留最终解释权!
Description
为了庆祝 NOI 的成功开幕,主办方为大家准备了一场寿司晚宴。小 G 和小 W 作为参加 NOI 的选手,也被邀请参加了寿司晚宴。
Input
输入文件的第 1 行包含 2 个正整数 n,p,中间用单个空格隔开,表示共有 n 种寿司,最终和谐的方案数要对 p 取模。
Output
输出一行包含 1 个整数,表示所求的方案模 p 的结果。
Sample Input
Sample Output
HINT
2≤n≤500
正解:状压DP+质因数分解
解题报告:
这道题的思想很巧妙QAQ
考虑直接算难以考虑,那么我们从题目给定的规则中可以发现其实,选择了一个数就相当于把这个数的质因子集合选了,因为为了确保第二个人选的和第一个人互质,就不能再选这个质因子。
考虑一个数最多有一个大于根号$500$的质因子,且可以特殊考虑,而小于等于根号$500$的质因子只有$8$个,所以我们可以使用状压$DP$来统计方案。
因为小于等于根号$500$的质因子可以通过状压判掉,但是大于根号$500$的部分我们必须想办法解决冲突和重复计算的问题。考虑将所有数包含的质因子集合,和大于根号$500$的质因子(如果没有就是$1$)预处理出来,按大于根号$500$的质因子排序,那么这个质因子相等的区间我们一起处理。
显然这相等的一整个区间,必须是只放入第一个人或者只放入第二个人或者都不放入,那么就可以DP了:
$f[s1][s2]$表示全局第一个人选择的集合为$s1$,第二个人选择的集合为$s2$时的方案数,接着把$f$的值赋给$g$,
$g[0、1][s1][s2]$表示第一个人选择的集合为$s1$,第二个人选择的集合为$s2$,同时当前这个大于根号$500$的质因子放入第一个人/第二个人的方案数。
做一遍$DP$,最后统计完整个相等的区间时,就赋值回$f$:$f[s1][s2]=g[0][s1][s2]+g[1][s1][s2]-f[s1][s2]$,表示的是两种情况相加,但是因为这个质因子两个都不放的情况算了两次,所以需要减掉一次。
注意$f$、$g$之间相互转换的时间和条件。
ps:不含大质因子的时候可以每次都统计一遍答案,因为已经可以用状态来防止非法情况了,无需特别考虑。
//It is made by ljh2000
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <ctime>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <string>
#include <complex>
using namespace std;
typedef long long LL;
const int MAXS = 257;
const int MAXN = 520;
const int end = 256;
int n,prime[12]={2,3,5,7,11,13,17,19};
LL p,f[MAXS][MAXS],g[2][MAXS][MAXS],ans;
//f[s1][s2]表示当前第一个人选的集合为s1,第二个人选的集合为s2的方案数
//g[0][s1][s2],表示对于当前大于根号500质因子相同的一个区间而言的,这个质因子分配给第一个人(或者不分配)的方案数;
//g[1][s1][s2]表示对于第二个人而言的 struct Number{
int S;//包含质因子的状态
int prime;//大于根号500的质因子,没有则是1
}a[MAXN]; inline bool cmp(Number q,Number qq){ return q.prime<qq.prime; } inline int getint(){
int w=0,q=0; char c=getchar(); while((c<'0'||c>'9') && c!='-') c=getchar();
if(c=='-') q=1,c=getchar(); while (c>='0'&&c<='9') w=w*10+c-'0',c=getchar(); return q?-w:w;
} inline void work(){
n=getint(); scanf("%lld",&p); int x;
for(int i=2;i<=n;i++) {
x=i;
for(int j=0;j<8;j++) {
if(x%prime[j]>0) continue;
a[i].S|=(1<<j);
while(x%prime[j]==0) x/=prime[j];
}
a[i].prime=x;
}
sort(a+2,a+n+1,cmp);
f[0][0]=1;
for(int i=2;i<=n;i++) {
if(i==2 || a[i].prime!=a[i-1].prime || a[i].prime==1) {
memcpy(g[0],f,sizeof(f));
memcpy(g[1],f,sizeof(f));
} for(int j=end-1;j>=0;j--)
for(int k=end-1;k>=0;k--) {
if((j&k)>0) continue;//不合法
if((a[i].S&k)==0) //不与第二个人冲突,则可以选入第一个人
g[0][ a[i].S | j ][k]+=g[0][j][k],g[0][ a[i].S | j ][k]%=p;
if((a[i].S&j)==0)
g[1][j][ a[i].S | k ]+=g[1][j][k],g[1][j][ a[i].S | k ]%=p;
} if(i==n || a[i].prime==1 || a[i].prime!=a[i+1].prime) {
for(int j=end-1;j>=0;j--)
for(int k=end-1;k>=0;k--) {
if((j&k)>0) continue;
/*!!!*/
f[j][k]=g[0][j][k]+g[1][j][k]-f[j][k];//去掉重复计算没有选当前这个质因子的情况
}
}
}
for(int i=end-1;i>=0;i--)
for(int j=end-1;j>=0;j--)
if((i&j)==0)
ans+=f[i][j],ans%=p;
ans+=p; ans%=p;
printf("%lld",ans);
} int main()
{
work();
return 0;
}
BZOJ4197 / UOJ129 [Noi2015]寿司晚宴的更多相关文章
- 【BZOJ4197】[Noi2015]寿司晚宴 状压DP+分解质因数
[BZOJ4197][Noi2015]寿司晚宴 Description 为了庆祝 NOI 的成功开幕,主办方为大家准备了一场寿司晚宴.小 G 和小 W 作为参加 NOI 的选手,也被邀请参加了寿司晚宴 ...
- 【bzoj4197】[Noi2015]寿司晚宴 分解质因数+状态压缩dp
题目描述 为了庆祝 NOI 的成功开幕,主办方为大家准备了一场寿司晚宴.小 G 和小 W 作为参加 NOI 的选手,也被邀请参加了寿司晚宴. 在晚宴上,主办方为大家提供了 n−1 种不同的寿司,编号 ...
- UOJ129 NOI2015 寿司晚宴 数论、状压DP
传送门 数论题\(n \leq 500\)肯定是什么暴力算法-- 注意到每一个数\(> \sqrt{n}\)的因子最多只有一个,这意味着\(> \sqrt{n}\)的因子之间是独立的,而只 ...
- [UOJ#129][BZOJ4197][Noi2015]寿司晚宴
[UOJ#129][BZOJ4197][Noi2015]寿司晚宴 试题描述 为了庆祝 NOI 的成功开幕,主办方为大家准备了一场寿司晚宴.小 G 和小 W 作为参加 NOI 的选手,也被邀请参加了寿司 ...
- [BZOJ4197][Noi2015]寿司晚宴
4197: [Noi2015]寿司晚宴 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 412 Solved: 279[Submit][Status] ...
- BZOJ 4197: [Noi2015]寿司晚宴( dp )
N^0.5以内的质数只有8个, dp(i, j, k)表示用了前i个大质数(>N^0.5), 2人选的质数(<=N^0.5)集合分别为j, k时的方案数. 转移时考虑当前的大质数p是给哪个 ...
- BZOJ_4197_[Noi2015]寿司晚宴_状态压缩动态规划
BZOJ_4197_[Noi2015]寿司晚宴_状态压缩动态规划 Description 为了庆祝 NOI 的成功开幕,主办方为大家准备了一场寿司晚宴.小 G 和小 W 作为参加 NOI 的选手,也被 ...
- [NOI2015]寿司晚宴 --- 状压DP
[NOI2015]寿司晚宴 题目描述 为了庆祝NOI的成功开幕,主办方为大家准备了一场寿司晚宴. 小G和小W作为参加NOI的选手,也被邀请参加了寿司晚宴. 在晚宴上,主办方为大家提供了n−1种不同的寿 ...
- BZOJ 4197: [Noi2015]寿司晚宴 状态压缩 + 01背包
4197: [Noi2015]寿司晚宴 Time Limit: 10 Sec Memory Limit: 512 MB Description 为了庆祝 NOI 的成功开幕,主办方为大家准备了一场寿 ...
随机推荐
- 爬虫实战【6】Ajax内容解析-今日头条图集
Ajax技术 AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML). Ajax并不是新的编程语言,而是一种使用现有标准的新方法,当然 ...
- EasyNVR对接EasyCloud视频云平台进行云端录像
EasyCloud视频云平台是一套能够接入各种类型流,进行统一的设备管理.直播.录像.回放的视频平台,同时,EasyCloud视频云平台集成了云端运维功能,在云端就可以直接维护和控制各个现场的软件运行 ...
- influxDB---Data Exploration
the group clause group by 返回的分组结果是根据用户指定的tag ,time interval. 1.group by tags 2.group by time interva ...
- coursera 《现代操作系统》 -- 第五周 同步机制(1)
临界区块(Critical section)指的是一个访问共用资源(例如:共用设备或是共用存储器)的程序片段,而这些共用资源有无法同时被多个线程访问的特性.(不是字面意思的一个区域,是程序片段的集合) ...
- UIApplication的理解
iPhone应用程序是由主函数main启动,它负责调用UIApplicationMain函数,该函数的形式如下所示: int UIApplicationMain ( int argc, char *a ...
- Linux中的awk命令
awk '条件1{动作1} 条件2{动作2} ...' 文件名 条件: BEGIN 在处理文件里的第一行数据之前执行 END 在处理完文件里的最后一行数据 ...
- HDFS权限管理指南(HDFS Permissions Guide)
综述 HDFS实现了一个类似POSIX模型的文件和文件夹权限管理模型.每一个文件盒文件夹都有一个所有者和一个组.文件或者文件夹可以通过权限区分是所有者还是组成员或是其他用户.对文件来说,r标示可以阅读 ...
- IDEA中创建maven web项目的详细部署
步骤一:首先先创建一个project,上次我说过了创建一个project就是一个工作空间,在这里就是创建一个maven的工作空间 步骤二:你要选择maven然后按照下面图片 的指示操作就可以了---& ...
- centos7 Mysql5.6 升级Mysql5.7
1 2. 卸载Mysql5.6 ,一共有三个包 要卸载: (1)先卸载mysql-server包 : 执行命令 yum remove mysql mysql-server (2)再卸载mysql-c ...
- Shell字符串操作
@1:子串削除 ${string#substring} 从$string 的开头位置截掉最短匹配的$substring. ${string##substring} 从$string 的开头位置截掉最长 ...