BZOJ_2734_[HNOI2012]集合选数_构造+状压DP

题意:《集合论与图论》这门课程有一道作业题,要求同学们求出{1, 2, 3, 4, 5}的所有满足以 下条件的子集:若 x 在该子集中,则 2x 和 3x 不能在该子集中。同学们不喜欢这种具有枚举性 质的题目,于是把它变成了以下问题:对于任意一个正整数 n≤100000,如何求出{1, 2,..., n} 的满足上述约束条件的子集的个数(只需输出对 1,000,000,001 取模的结果),现在这个问题就 交给你了。

分析:

我们构造出一个矩阵

$\begin{matrix}
    1&2^03^1&2^03^2\\
    2^13^0&2^13^1&2^13^2\\
    2^23^0&2^23^1&2^23^2\\
\end{matrix}
$

发现矩阵的相邻两个格子的数不能同时取

状压DP一下

要把所有不在矩阵中的数当作1重新构造,比如5,7等等

每个矩阵的结果乘起来就是答案

代码:

#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define LL long long
LL p=1000000001,A,f[18][1<<12];
int vis[100050],s[18],mat[18][18];
LL ans=1;
void build(int x){
int n=1,m=1,now=x;
while(now*3<=A)m++,now*=3;
now=x;
while(now*2<=A)n++,now<<=1;
int mask=(1<<m)-1;
memset(s,0,sizeof(s));
memset(f,0,sizeof(f));
memset(mat,0,sizeof(mat));
mat[1][1]=x;vis[x]=1;
for(int i=2;i<=m;i++){
mat[1][i]=mat[1][i-1]*3;
vis[mat[1][i]]=1;
}
s[1]=mask;
for(int i=2;i<=n;i++){
mat[i][1]=mat[i-1][1]*2;
vis[mat[i][1]]=1;
for(int j=2;j<=m;j++){
mat[i][j]=mat[i-1][j]*2;
if(mat[i][j]>A){
s[i]=mask^((1<<m-j+1)-1);
break;
}
vis[mat[i][j]]=1;
}
if(!s[i])s[i]=mask;
}
f[0][0]=1;
s[0]=mask;
for(int i=0;i<n;i++){
for(int j=0;j<=mask;j++){
if((j|s[i])!=s[i])continue;
if(j&(j<<1))continue;
for(int k=0;k<=mask;k++){
if((k|s[i+1])!=s[i+1])continue;
if(k&(k<<1))continue;
if(j&k)continue;
f[i+1][k]+=f[i][j];
f[i+1][k]%=p;
}
}
}
LL re=0;
for(int i=0;i<=mask;i++)re+=f[n][i],re%=p;
ans=re*ans%p; /*for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
printf("%d ",mat[i][j]);
}
puts("");
}*/ /*for(int i=1;i<=n;i++){
printf("%d\n",s[i]);
}*/
}
int main(){
scanf("%lld",&A);
for(int i=1;i<=A;i++){
if(!vis[i])build(i);
}
printf("%lld",ans);
}

BZOJ_2734_[HNOI2012]集合选数_构造+状压DP的更多相关文章

  1. [HNOI2012]集合选数(构造,状态压缩,DP)

    神仙题. 莫名其妙的就试一试把所有数放进一个类似矩阵的东西里面. 首先把 \(1\) 放到左上角,然后在每个数的右边放它的 \(3\) 倍(大于 \(n\) 就不用放了),下面放它的 \(2\) 倍( ...

  2. [HNOI2012]集合选数 --- 状压DP

    [HNOI2012]集合选数 题目描述 <集合论与图论>这门课程有一道作业题,要求同学们求出\({1,2,3,4,5}\)的所有满足以 下条件的子集:若 x 在该子集中,则 2x 和 3x ...

  3. bzoj 2734: [HNOI2012]集合选数 状压DP

    2734: [HNOI2012]集合选数 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 560  Solved: 321[Submit][Status ...

  4. $HNOI2012\ $ 集合选数 状压$dp$

    \(Des\) 求对于正整数\(n\leq 1e5\),{\(1,2,3,...,n\)}的满足约束条件:"若\(x\)在该子集中,则\(2x\)和\(3x\)不在该子集中."的子 ...

  5. 洛谷$P3226\ [HNOI2012]$集合选数 状压$dp$

    正解:$dp$ 解题报告: 传送门$QwQ$ 考虑列一个横坐标为比值为2的等比数列,纵坐标为比值为3的等比数列的表格.发现每个数要选就等价于它的上下左右不能选. 于是就是个状压$dp$板子了$QwQ$ ...

  6. 2734: [HNOI2012]集合选数

    2734: [HNOI2012]集合选数 链接 分析: 转化一下题意. 1 3 9 27... 2 6 18 54... 4 12 36 108... 8 24 72 216... ... 写成这样的 ...

  7. 2734: [HNOI2012]集合选数 - BZOJ

    Description <集合论与图论>这门课程有一道作业题,要求同学们求出{1, 2, 3, 4, 5}的所有满足以 下条件的子集:若 x 在该子集中,则 2x 和 3x 不能在该子集中 ...

  8. [HNOI2012]集合选数(状压DP+构造)

    题目要求若出现x,则不能出现2x,3x 所以我们考虑构造一个矩阵 \(1\ 2\ 4 \ 8--\) \(3\ 6\ 12\ 24--\) \(9\ 18\ 36--\) \(--\) 不难发现,对于 ...

  9. BZOJ 2734: [HNOI2012]集合选数 [DP 状压 转化]

    传送门 题意:对于任意一个正整数 n≤100000,如何求出{1, 2,..., n} 的满足若 x 在该子集中,则 2x 和 3x 不能在该子集中的子集的个数(只需输出对 1,000,000,001 ...

随机推荐

  1. IndexedDB,FileSystem- 前端数据库,文件管理系统

    "我们不再需要下载并且安装软件.一个简单的web浏览器和一个可供使用的互联网就足以让我们在任何时间, 任何地点, 还有任何平台上使用任何web应用程序." web应用很酷, 但是相 ...

  2. miniUI input设置默认值,js获取年月注意事项,数据库nvl函数使用

    2017-6-5周一,今天碰到的一个需求是:两税附征模块进入页面筛选时间默认值为当前月的上一个月,并根据筛选结果显示数据,我们用的框架为miniUI. 坑1: 默认值设置,刚刚接触miniUI,对里面 ...

  3. 简单验证码的识别:Bitmap类的使用

    验证码的智能识别是一项比较复杂的工作,甚至需要掌握点图像学的知识. 当然对于写程序的来说不用那么深入,只需要掌握几个常规步骤就行了. 验证码图像识别步骤:1.获取图像 2.清除边框 3.灰度处理 4. ...

  4. gdb命令中attach使用

    [测试程序] 我们先看看我们的测试程序: /* in eg1.c */ int wib(int no1, int no2) {         int result, diff;         di ...

  5. Ubuntu 下命令安装 Java

    1. 使用 java -version 查看系统是否存在 jdk. 2. ubuntu使用的是openjdk,所以我们需要先找到合适的jdk版本.在命令行中输入命令:apt-cache search ...

  6. Java 线程同步组件 CountDownLatch 与 CyclicBarrier 原理分析

    1.简介 在分析完AbstractQueuedSynchronizer(以下简称 AQS)和ReentrantLock的原理后,本文将分析 java.util.concurrent 包下的两个线程同步 ...

  7. 箭头函数不会修改this

    function Person () { this.name = 'little bear', this.age = 18 setTimeout(()=>{ console.log(this ) ...

  8. 第三章 C++的三种基本控制结构

    0x C++提供的三种基本控制结构 顺序结构:按照先后顺序依次执行程序中的语句 选择结构:按照给定条件有选择地执行程序中的语句 循环语句:按照给定规则重复地执行程序中的语句 1x 第一节 C++语句 ...

  9. mina框架tcpt通讯接收数据断包粘包处理

    用mina做基于tcp,udp有通讯有段时间了,一直对编码解码不是很熟悉,这次做项目的时候碰到了断包情况,贴一下解决过程, 我接受数据格式如下图所示: unit32为c++中数据类型,代表4个字节,由 ...

  10. Scrapy爬虫框架第三讲(linux环境)

    下面我们来学习下Spider的具体使用: 我们已上节的百度阅读爬虫为例来进行分析: 1 # -*- coding: utf-8 -*- 2 import scrapy 3 from scrapy.li ...