\(Des\)

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

\(Sol\)

是一道很妙的构造+状压\(dp\)题吖.

我最开始想这题的时候画了一个如下的图.对于每一个点,左儿子是它的两倍,右儿子是它的三倍.

约束条件是:连了边的两个点是不可以同时选的,也就是只能隔一个选一个,但是这样显然不好做.于是考虑能不能再转化一下.仔细观察这个图会发现它特别像一棵树,但又不是,因为一个点有两个父亲,这是因为一个数可能是一个数的两倍同时又是另外一个数的三倍.再观察一下会发现这个图似乎是由许多小菱形组成的,于是把菱形拉成正方形会发现得到了一个倒三角.如下:

显然我们可以把这个倒三角填满得到一个网格图.对于每一个点,它的下面是它的两倍,右边是它的三倍.这样一来,约束条件就变成了选了一个数,就不能选与它相邻的数(上,下,左,右).转化之后就成为了一般的状压$dp $解决的问题.但是,注意到这个表格并不能涵盖所有的数,我们需要对没有被涵盖的数再建一个如上的网格图,最后乘法原理统计下答案就好了.

温馨提醒​

大数组别用\(memset\),你很有可能会向我一样\(T\)掉.

\(Code\)

Code

```cpp
#include
#define il inline
#define Ri register int
#define go(i,a,b) for(Ri i=a;i=b;--i)
#define e(i,u) for(Ri i=b[u];i;i=a[i].nt)
#define mem(a,b) memset(a,b,sizeof(a))
#define ll long long
#define db double
#define inf 2147483647
using namespace std;
il int read()
{
Ri x=0,y=1;char c=getchar();
while(c'9'){if(c=='-')y=-1;c=getchar();}
while(c>='0'&&cb[30];
bool vis[N];
il void build(Ri x)
{
mem(h,0);
while(xmod)f[i][j]-=mod;
}
}
ll ret=0;
go(j,0,(int)b[h[0]].size()-1)
{
ret=ret+f[h[0]][j];
if(ret>mod)ret-=mod;
}
return ret;
}
int main()
{
n=read();
go(i,1,n)
{
if(vis[i])continue;
build(i);as=as*sol();if(as>mod)as%=mod;
}
printf("%lld\n",as);
return 0;
}

  1. <details>

随机推荐

  1. 待性能改善的一个SQL

    select t.*, t.rowid from tb_tk_datasakusei_ctrl t; alter table ATOMBB.TB_TK_JISSEKI_INFO_DETAIL add ...

  2. Oracle中的Union、Union All、Intersect、Minus[转]

    众所周知的几个结果集集合操作命令,今天详细地测试了一下,发现一些问题,记录备考. 假设我们有一个表Student,包括以下字段与数据: drop table student; create table ...

  3. Where是深复制

    从一个List中通过Where过滤出来的子List或Fist出来的单独元素,与原List是深复制关系.也就是说修改子list,或单独元素,并不会影响原List中的对象. 如:Geom g = Geom ...

  4. Android读取sd卡

    public static String[] getStoragePaths() { List<String> pathsList = new ArrayList<String> ...

  5. iptables 限制访问规则

    iptables -I INPUT 1 -m state --state RELATED,ESTABLISHED -j ACCEPT把这条语句插在input链的最前面(第一条),对状态为ESTABLI ...

  6. iptables 规则(Rules)

    iptables的每一条规则(rule),都是由两部分组成的,第一部分包含一或多个「过滤条件」其作用是检查包是否符合处理条件(所有条件都必须成立才算数) :第而部分称为「目标」,用於決定如何处置符合条 ...

  7. Getting started with the basics of programming exercises_5

    1.编写函数,把由十六进制数字组成的字符串转换为对应的整型值 编写函数htoi(s),把由十六进制数字组成的字符串(包含可选的前缀0x或0X)转换为与之等价的整型值.字符串中允许包含的数字包括:0~9 ...

  8. PageHelper实现分页查询

    PageHelper是基于拦截器实现的myBatis分页插件 PageHelper的Github主页 : https://github.com/pagehelper/Mybatis-PageHelpe ...

  9. 洛谷P1488 肥猫的游戏 题解 博弈论入门

    题目链接:https://www.luogu.org/problem/P1488 其实这道题目我只需要 \(n\) 以及黑色三角形的三个端点编号就可以了. 我们假设在一个 \(n\) 边形中,黑色三角 ...

  10. 程序中打开IE浏览器并访问指定地址

    最简单的方法 Process.Start("iexplore.exe");  //直接打开IE浏览器(打开默认首页)            Process.Start(" ...