【刷题】BZOJ 2734 [HNOI2012]集合选数
Description
《集合论与图论》这门课程有一道作业题,要求同学们求出{1, 2, 3, 4, 5}的所有满足以 下条件的子集:若 x 在该子集中,则 2x 和 3x 不能在该子集中。同学们不喜欢这种具有枚举性 质的题目,于是把它变成了以下问题:对于任意一个正整数 n≤100000,如何求出{1, 2,..., n} 的满足上述约束条件的子集的个数(只需输出对 1,000,000,001 取模的结果),现在这个问题就 交给你了。
Input
只有一行,其中有一个正整数 n,30%的数据满足 n≤20。
Output
仅包含一个正整数,表示{1, 2,..., n}有多少个满足上述约束条件 的子集。
Sample Input
4
Sample Output
8
【样例解释】
有8 个集合满足要求,分别是空集,{1},{1,4},{2},{2,3},{3},{3,4},{4}。
Solution
考虑构造这样一个矩阵
x & 3x & 9x & 27x & \cdots & \\ \\
2x & 6x & 18x & 54x & \cdots & \\ \\
4x & 12x & 36x & 108x & \cdots & \\ \\
8x & 24x & 72x & 216x & \cdots & \\ \\
\vdots & \vdots & \vdots & \vdots & \ddots &\\
\end{bmatrix}
\]
那么对于一个数 \(x\) ,与它有冲突关系的数就都选出来了,我们只要在矩阵上选数,并且相邻位置不能选到就可以了
这一步就是个状压dp模板题
对于不在同一矩阵的每一种 \(x\) ,都构造一个矩阵,计算答案。这些矩阵之间互不干扰,所以直接乘起来就好了
#include<bits/stdc++.h>
#define ui unsigned int
#define ll long long
#define db double
#define ld long double
#define ull unsigned long long
const int MAXN=100000+10,Mod=1e9+1;
int n,G[20],cnt,p[MAXN],vis[MAXN];
ll f[20][2000],ans;
template<typename T> inline void read(T &x)
{
T data=0,w=1;
char ch=0;
while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
if(ch=='-')w=-1,ch=getchar();
while(ch>='0'&&ch<='9')data=((T)data<<3)+((T)data<<1)+(ch^'0'),ch=getchar();
x=data*w;
}
template<typename T> inline void write(T x,char ch='\0')
{
if(x<0)putchar('-'),x=-x;
if(x>9)write(x/10);
putchar(x%10+'0');
if(ch!='\0')putchar(ch);
}
template<typename T> inline void chkmin(T &x,T y){x=(y<x?y:x);}
template<typename T> inline void chkmax(T &x,T y){x=(y>x?y:x);}
template<typename T> inline T min(T x,T y){return x<y?x:y;}
template<typename T> inline T max(T x,T y){return x>y?x:y;}
inline ll qexp(ll a,ll b)
{
ll res=1;
while(b)
{
if(b&1)res=res*a%Mod;
a=a*a%Mod;
b>>=1;
}
return res;
}
inline bool check(int st)
{
return (st&(st<<1))||(st&(st>>1));
}
inline ll solve(ll x)
{
memset(G,0,sizeof(G));
int w=0,h=0;
while(x*qexp(2,w)<=n)++w;
while(x*qexp(3,h)<=n)++h;
for(register int i=1;i<=w;++i)
for(register int j=1;j<=h;++j)
if(qexp(2,i-1)*qexp(3,j-1)*x<=n)vis[qexp(2,i-1)*qexp(3,j-1)*x]=1,G[i]|=(1<<h-j);
cnt=0;
for(register int st=0;st<(1<<h);++st)
if(!check(st))p[++cnt]=st;
memset(f,0,sizeof(f));
for(register int i=1;i<=w;++i)
for(register int j=1;j<=cnt;++j)
if((p[j]|G[i])==G[i])
{
if(i==1)f[i][j]++;
else
for(register int k=1;k<=cnt;++k)
if((p[k]|G[i-1])==G[i-1]&&!(p[j]&p[k]))(f[i][j]+=f[i-1][k])%=Mod;
}
ll res=0;
for(register int i=1;i<=cnt;++i)
if((p[i]|G[w])==G[w])(res+=f[w][i])%=Mod;
return res;
}
int main()
{
read(n);ans=1;
for(register int i=1;i<=n;++i)
if(!vis[i])ans=1ll*ans*solve(i)%Mod;
write(ans,'\n');
return 0;
}
【刷题】BZOJ 2734 [HNOI2012]集合选数的更多相关文章
- bzoj 2734: [HNOI2012]集合选数 状压DP
2734: [HNOI2012]集合选数 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 560 Solved: 321[Submit][Status ...
- bzoj 2734: [HNOI2012]集合选数
题目描述 <集合论与图论>这门课程有一道作业题,要求同学们求出{1, 2, 3, 4, 5}的所有满足以 下条件的子集:若 x 在该子集中,则 2x 和 3x 不能在该子集中. 同学们不喜 ...
- BZOJ 2734 [HNOI2012]集合选数 (状压DP、时间复杂度分析)
题目链接 https://www.lydsy.com/JudgeOnline/problem.php?id=2734 题解 嗯早就想写的题,昨天因为某些不可告人的原因(大雾)把这题写了,今天再来写题解 ...
- BZOJ 2734: [HNOI2012]集合选数 [DP 状压 转化]
传送门 题意:对于任意一个正整数 n≤100000,如何求出{1, 2,..., n} 的满足若 x 在该子集中,则 2x 和 3x 不能在该子集中的子集的个数(只需输出对 1,000,000,001 ...
- bzoj 2734 [HNOI2012]集合选数 状压DP+预处理
这道题很神啊…… 神爆了…… 思路大家应该看别的博客已经知道了,但大部分用的插头DP.我加了预处理,没用插头DP,一行一行来,速度还挺快. #include <cstdio> #inclu ...
- 2734: [HNOI2012]集合选数
2734: [HNOI2012]集合选数 链接 分析: 转化一下题意. 1 3 9 27... 2 6 18 54... 4 12 36 108... 8 24 72 216... ... 写成这样的 ...
- 2734: [HNOI2012]集合选数 - BZOJ
Description <集合论与图论>这门课程有一道作业题,要求同学们求出{1, 2, 3, 4, 5}的所有满足以 下条件的子集:若 x 在该子集中,则 2x 和 3x 不能在该子集中 ...
- 【BZOJ】2734: [HNOI2012]集合选数
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2734 考虑$N=4$的情况: \begin{bmatrix} 1&3 &X ...
- BZOJ_2734_[HNOI2012]集合选数_构造+状压DP
BZOJ_2734_[HNOI2012]集合选数_构造+状压DP 题意:<集合论与图论>这门课程有一道作业题,要求同学们求出{1, 2, 3, 4, 5}的所有满足以 下条件的子集:若 x ...
随机推荐
- mysql自定义函数并在存储过程中调用,生成一千万条数据
mysql 自定义函数,生成 n 个字符长度的随机字符串 -- sql function delimiter $$ create function rand_str(n int) returns VA ...
- Redis Replication
Replication 官网说明:http://www.redis.io/topics/replication Redis使用异步复制; 一个Master可以有多个Slaves; Slaves可以接收 ...
- jpbm工作流框架
一:JBPM是什么?有什么用?能解决什么问题? 现实生活中有很多需要走一些流程的过程,比如请假流程,报销流程等,使用工作流框架,即可写一个流程即可,添加流程时不在繁琐的建立新的各种配置. 1:jBPM ...
- Java转python第一天
1.python xx.py 2.字符串可以与数字相乘 str = "abc" msg = str*3 print(msg) # 结果:abcabcabc 3.换行用三个单引号 ' ...
- 20155217《网络对抗》Exp04 恶意代码分析
20155217<网络对抗>Exp04 恶意代码分析 实践内容 使用schtasks指令监控系统运行 使用sysmon工具监控系统运行 使用virscan分析恶意软件 使用systrace ...
- 20155302《网络对抗》Exp8 Web基础
20155302<网络对抗>Exp8 Web基础 实验内容 (1).Web前端HTML(0.5分) 能正常安装.启停Apache.理解HTML,理解表单,理解GET与POST方法,编写一个 ...
- mfc CListCtrl 报表格式
知识点: CListCtrl报表格式 CListCtrl报表格式添加列 CListCtrl报表格式添加行 CListCtrl报表格式设置单元格 一.CListCtrl报表格式 类名:SysListVi ...
- C++ STL 学习笔记__(8)map和multimap容器
10.2.9 Map和multimap容器 map/multimap的简介 ² map是标准的关联式容器,一个map是一个键值对序列,即(key,value)对.它提供基于key的快速检索能力. ² ...
- PowerBI开发 第五篇:关系和交互
PowerBI 使用 内存的列式数据库 VertiPaq,用于对已发布的数据集进行数据压缩和快速处理,能够使PowerBI报表执行脱机访问,面向列的处理,高度优化对1:N关系的处理性能.关系是数据分析 ...
- 巧用Alt 键
1,查看表的元数据信息 在TSQL 查询编辑器中,选中一个表,如图 点击Alt+F1,就可以查看表的元数据,列的定义和ID列等 2,使用Alt批量插入逗号 在TQL语句中,有时为了使用 in 子句,必 ...