[NOI2015]寿司晚宴——状压dp
题目转化:将2~n的数分成两组,可以不选,使得这两组没有公共的质因子。求方案数。
选择了一个数,相当于选择了它的所有质因子。
30分:
发现,n<=30的时候,涉及到的质因子也就10个。2,3,5,7,11,13,19,23,29
直接状压。f[i][A][B] 前i个数,第一个人的质因子选择状态A,第二人B,的方案数。(第一维可以滚动,当然,可以倒序循环直接省略)
每个数质因数分解,前八个质因子,压成二进制数,转移直接按位或。
100分:
质因子太多状压不了。
公理:一个数>=sqrt(n)的质因子最多只有一个。(显然啊,否则质因数分解就超过了n)
所以,对于最大质因子>=sqrt(n)的数,根据最大质因子分类,质因子相同的,要么都考虑进入A,要么都考虑进入B,要么都不选。
设g[0/1][A][B]表示这一阶段,数字都考虑进入A/B的方案数。初值和f一样。
最后,f[A][B]=g[0][A][B]+g[1][A][B]-f[A][B] 因为,所有数都不选的方案计算了两次,所以减一次。
对于最大质因子<sqrt(n)的数,直接根据上面的转移就好。
统计答案时,选择A&B=0 的方案数。
具体看代码:(luogu要开O2)
- #include<bits/stdc++.h>
- using namespace std;
- typedef long long ll;
- const int N=+;
- int n,mod;
- struct node{
- int has;
- int z;
- }num[N];
- bool cmp(node a,node b){
- return a.z<b.z;
- }
- ll ans;
- int zh[N],cnt;
- int ps[N],tot;
- int vis[N];
- bool in[N];
- void sieve(){
- for(int i=;i<=n;i++){
- if(!vis[i]){
- tot++;ps[tot]=i;
- vis[i]=i;
- }
- for(int j=;j<=tot;j++){
- if(i*ps[j]>n) break;
- vis[i*ps[j]]=ps[j];
- if(i%ps[j]==) break;
- }
- }
- }
- void sol(int x){
- cnt=;
- int kk=x;
- for(int i=;i<=tot;i++){
- if(x%ps[i]==){
- zh[++cnt]=i;//prime's id
- while(x%ps[i]==) x/=ps[i];
- }
- }
- for(int i=;i<=cnt;i++){
- if(zh[i]>) num[kk].z=zh[i];
- else num[kk].has|=(<<zh[i]-);
- }
- if(!num[kk].z) num[kk].z=;
- }
- ll f[<<][<<];
- ll g[][<<][<<];
- int main()
- {
- scanf("%d%d",&n,&mod);
- sieve();
- for(int i=;i<=n;i++)sol(i);
- sort(num+,num+n+,cmp);
- f[][]=;
- for(int i=;i<=n;i++){
- if(num[i].z==){
- for(int A=(<<)-;A>=;A--)
- for(int B=(<<)-;B>=;B--){
- f[A|num[i].has][B]=(f[A|num[i].has][B]+f[A][B])%mod;
- f[A][B|num[i].has]=(f[A][B|num[i].has]+f[A][B])%mod;
- }
- }
- else{
- int zz=num[i].z;
- memcpy(g[],f,sizeof f);
- memcpy(g[],f,sizeof f);
- while(num[i].z==zz&&i<=n){
- for(int A=(<<)-;A>=;A--)
- for(int B=(<<)-;B>=;B--){
- g[][A|num[i].has][B]=(g[][A|num[i].has][B]+g[][A][B])%mod;
- g[][A][B|num[i].has]=(g[][A][B|num[i].has]+g[][A][B])%mod;
- }
- i++;
- }
- i--;
- for(int A=(<<)-;A>=;A--)
- for(int B=(<<)-;B>=;B--){
- f[A][B]=((g[][A][B]+g[][A][B])%mod-f[A][B])%mod;if(f[A][B]<) f[A][B]+=mod;
- }
- }
- }
- for(int A=;A<=(<<)-;A++)
- for(int B=;B<=(<<)-;B++){
- if((A&B)==) ans=(ans+f[A][B])%mod;
- }
- printf("%lld",ans);
- return ;
- }
总结:
这个题目其实很巧妙。
思路:
1.互质即没有公共质因子,所以选择一个数就是选择一些质因子。转化题意。
2.30分,发现质因子很小,可以直接状压。
3.100分,发现每个数>=sqrt的质因子最多只有一个。暴力分组考虑,每组内统计都放进A/B的方案。
关键的突破口还是题意的转化。以及第三点。
[NOI2015]寿司晚宴——状压dp的更多相关文章
- [NOI2015]寿司晚宴 --- 状压DP
[NOI2015]寿司晚宴 题目描述 为了庆祝NOI的成功开幕,主办方为大家准备了一场寿司晚宴. 小G和小W作为参加NOI的选手,也被邀请参加了寿司晚宴. 在晚宴上,主办方为大家提供了n−1种不同的寿 ...
- 【BZOJ4197】[Noi2015]寿司晚宴 状压DP+分解质因数
[BZOJ4197][Noi2015]寿司晚宴 Description 为了庆祝 NOI 的成功开幕,主办方为大家准备了一场寿司晚宴.小 G 和小 W 作为参加 NOI 的选手,也被邀请参加了寿司晚宴 ...
- B4197 [Noi2015]寿司晚宴 状压dp
这个题一开始想到了唯一分解定理,然后状压.但是显然数组开不下,后来想到每个数(n<500)大于19的素因子只可能有一个,所以直接单独存就行了. 然后正常状压dp就很好搞了. 题干: Descri ...
- bzoj4197 [Noi2015]寿司晚宴——状压DP
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4197 首先,两个人选的数都互质可以看作是一个人选了一个数,就相当于选了一个质因数集合,另一个 ...
- BZOJ 4197: [Noi2015]寿司晚宴 状压dp+质因数分解
挺神的一道题 ~ 由于两个人选的数字不能有互质的情况,所以说对于一个质因子来说,如果 1 选了,则 2 不能选任何整除该质因子的数. 然后,我们发现对于 1 ~ 500 的数字来说,只可能有一个大于 ...
- 【BZOJ-4197】寿司晚宴 状压DP
4197: [Noi2015]寿司晚宴 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 694 Solved: 440[Submit][Status] ...
- 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 ...
随机推荐
- [译]Kubernetes 分布式应用部署和人脸识别 app 实例
原文地址:KUBERNETES DISTRIBUTED APPLICATION DEPLOYMENT WITH SAMPLE FACE RECOGNITION APP 原文作者:skarlso 译文出 ...
- webpack教程(一)——初体验
首先全局安装webpack,再npm初始化一个项目,并局部安装webpack开发工具 $ npm install webpack -g npm init (项目名称) $ npm install we ...
- 关于Runtime error
别人说的,但我感觉是因为你的操作是不符合语言规定的,让编译器无法识别,运行不出
- PairProject-电梯调度程序结对编程
结对编程人员:184/050 1 结对编程 1.1 结对编程的优缺点 优点: ● 与单独开发相比,结对能够使人们在压力之下保持更好的状态.结对编程鼓励双方保持代码的高质量,即使在出现了让人不得不飞快地 ...
- Scrum Meeting 5
第五次会议 No_00:工作情况 No_01:任务说明 待完成 已完成 No_10:燃尽图 No_11:照片记录 待更新 No_100:代码/文档签入记录 No_101:出席表 ...
- Github介绍
Git是一个分布式的版本控制系统,最初由LinusTorvalds编写,用作Linux内核代码的管理.在推出后,Git在其它项目中也取得了很大成功,尤其是在Ruby社区中.包括Rubinius和Mer ...
- 『编程题全队』Beta 阶段冲刺博客五
1.提供当天站立式会议照片一张 2.每个人的工作 (有work item 的ID) (1) 昨天已完成的工作 孙志威: 1.为新建提醒框添加了正则匹配限制 2.添加了新建Reminder的功能 3.初 ...
- Linux下Vim使用备忘
1.Insert键,决定是Insert模式还是Replace模式. 2.Esc键,退出编辑模式(Insert Or Replace). 3.:wq (ZZ) 保存并退出Vim. http://caib ...
- oracle mysql gbk varchar varchar2
http://www.cnblogs.com/kxdblog/p/4042331.html https://wenku.baidu.com/view/97524e0f844769eae009ed80. ...
- node的consoidate的插件统一
使用consolidate.ejs.的这种形式. let express = require('express'); let app = express(); app.set('views','返回的 ...