链接:P6075

前言:

虽然其他大佬们的走分界线的方法比我巧妙多了,但还是提供一种思路。


题意:

%&¥……@#直接看题面理解罢。


分析过程:

看到这样的题面我脑里第一反应就是DP,但是看到nk的范围只能作罢。想到各种柿子又根本推不出来,于是颓废地打了个复杂度算不来的貌似是 \(2^{n^3}\) 的深搜。于是有以下测试:

input      output

1 2         4

2 2         16

3 2         64

1 3         8

2 3         64

3 3        512

于是我们惊喜地发现答案貌似就是\(2^{kn}\)。但这个答案到底是怎么来的呢?


证明:

我们发现对这道题,所谓集合是可以拆解成n个元素分别处理的,可将其视为从三角形左上角起向右下进行连续的覆盖,如图:

那么设一个元素在大小为k的三角形内的覆盖方案数为 \(f(k)\) ,那么n个元素的方案总数即为 \(f(k)^n\) 。接下来来推 \(f(k)\) ,注意以下推理仍只关注一个元素。

对于一个大小为k的三角形,我们着重分析最下面一行,因为去掉这一行就能转化为更小的三角形,将覆盖,未覆盖以及任意取值分别看做“1”,“0”,和“?”,那么根据题意,这一行的状况只能是前面m个1,后面k-m个0,分情况讨论。

  • 如果这行全部为零,即 :

发现当前的方案数即为上面未确定三角形的方案数\(f(k-1)\)。

  • 如果前面有 m \((1\le m< k-1 )\) 个1,即:

发现当前的方案数即为右上角缺失的三角形的方案数\(f(k-1-m)\)。

  • 如果前面有k-1个1,即:

那么最后一位可填0或1,共2种方案。

总结一下,发现第一种和第二种可合并为\(\sum\limits_{i=1}^{k-1}f(i)\),为了美观,我们设 \(f(0)\) 为2,即可将第三种情况也合并,即:

\(f(k)=\sum\limits_{i=0}^{k-1}f(i),f(0)=2\)

  • 当\(k=1\)时

\(f(1)=f(0)=2=2^1\)

  • 当\(k>1\)时

因为\(f(k-1)=\sum\limits_{i=0}^{k-2}f(i)\)

所以\(f(k)=\sum\limits_{i=0}^{k-1}f(i)=\sum\limits_{i=0}^{k-2}f(i)+f(k-1)=2*f(k-1)\)

综上,\(f(k)=2^k\)

那么那么n个元素的方案总数即为\(f(k)^n\)即\(2^{kn}\)。


优化:

呐有人就要问了这不就是个快速幂板子题吗,有什么优化?对不起的确是有的。

由于我们取模的数1,000,000,007是个质数,所以有费马小定理:\(a^{p-1}\equiv 1\pmod p\),也就是说我们可以对指数取模从而减少那么几次运算量,即\(2^{kn\mod 1000000006}\)


代码:

不就是个快速幂板子吗,就不放代码了。


题外话:

很睿智的作者看到 nk 的范围大,于是反手就把k*n对1,000,000,007取了个模。(100->40)

有人就要问了,这道绿题你写这么长给谁看啊?没错这篇题解就是我用来练\(\LaTeX\)的!

洛谷 P6075 [JSOI2015]子集选取的更多相关文章

  1. 洛谷 P5502 - [JSOI2015]最大公约数(区间 gcd 的性质+分治)

    洛谷题面传送门 学校模拟赛的某道题让我联想到了这道题-- 先讲一下我的野鸡做法. 首先考虑分治,对于左右端点都在 \([L,R]\) 中的区间我们将其分成三类:完全包含于 \([L,mid]\) 的区 ...

  2. BZOJ4475[Jsoi2015]子集选取——递推(结论题)

    题目描述 输入 输入包含一行两个整数N和K,1<=N,K<=10^9 输出 一行一个整数,表示不同方案数目模1,000,000,007的值. 样例输入 2 2 样例输出 16   可以发现 ...

  3. BZOJ4475 [Jsoi2015]子集选取

    Description 有一些\(\{1\dots n\}\)的子集\(A_{i,j}, 1\leq j\leq i\leq k\)共\(\frac{k(k+1)}2\)个,满足\(A_{i,j}\s ...

  4. [题解] LuoguP6075 [JSOI2015]子集选取

    传送门 ps: 下面\(n\)和\(k\)好像和题目里的写反了...将就着看吧\(qwq\) 暴力打个表答案就出来了? 先写个结论,答案就是\(2^{nk}\). 为啥呢? 首先你需要知道,因为一个集 ...

  5. BZOJ4475: [Jsoi2015]子集选取【找规律】【数学】

    Description Input 输入包含一行两个整数N和K,1<=N,K<=10^9 Output 一行一个整数,表示不同方案数目模1,000,000,007的值. Sample In ...

  6. [BZOJ4475][JSOI2015]子集选取[推导]

    题意 题目链接 分析 显然可以看成一个位数为 \(n\) 的二进制数然后每一位分开考虑然后求和.最后的答案是 \(w^n\) 的形式. 考虑一个dp. 定义状态 \(f_{i}\) 表示选择了长度为 ...

  7. BZOJ4475 JSOI2015子集选取(动态规划)

    数据范围过大说明这个题和组合一点关系也没有,答案基本上肯定是ab的形式了.暴力打表感觉不太好写,找到当年的题面发现还有个样例是6 40 401898087,于是暴力找ab=401898087的数,发现 ...

  8. 【BZOJ4475】 [Jsoi2015]子集选取

    题目描述 数据范围 \(1\leq N,K \leq 10^9\) \(solution\) 集合S中每个元素互不影响,不妨依次考虑其中一个元素在三角形中的出现情况 问题转化为一个\(0/1\)的三角 ...

  9. bzoj 4475: [Jsoi2015]子集选取

    233,扒题解的时候偷瞄到这个题的题解了,,GG 暴力发现是2^(nm),然后就是sb题了 #include <bits/stdc++.h> #define LL long long us ...

随机推荐

  1. 学习Tomcat(二)之容器概览

    Tomcat容器的Server模块有管理容器的启动和关闭.管理了容器内的服务组件Service.管理了全局JNDI资源的功能,对Tomcat容器的生命周期管理有重要意义.Tomcat的服务组件则是To ...

  2. Zookeeper Acl权限 超级用户权限 怎么跳过ACL密码/账户验证

    Zookeeper的一个节点不知道什么原因无法删除了,查看日志发现是没有权限, 我们之前使用ACL进行Zookeeper节点的权限管理. 可以解决以下三种但不限于以下三种问题: 1.在设置Acl权限时 ...

  3. POJ2352 Stars (静态二叉检索树)

    https://vjudge.net/problem/POJ-2352 分析: 由于是按照y坐标的升序,y坐标向等的按x的升序的顺序给出星星.那么某个星星的等级数就是在他前面x坐标小于等于他的x坐标的 ...

  4. 【TP3.2.3】addAll方法的坑

    问题:做一个导入Excel到数据库的功能中需要用到addAll功能,但是每次执行到addAll()时都会报错,如下 Insert value list does not match column li ...

  5. 使用uView UI+UniApp开发微信小程序--判断用户是否登录并跳转

    在<使用uView UI+UniApp开发微信小程序>的随笔中,介绍了基于uView UI+UniApp开发微信小程序的一些基础知识和准备工作,其中也大概介绍了一下基本的登录过程,本篇随笔 ...

  6. (转载)深入理解MDL元数据锁

    作者:MySQL技术本文为作者原创,转载请注明出处:https://www.cnblogs.com/kunjian/p/11993708.html 前言: 当你在MySQL中执行一条SQL时,语句并没 ...

  7. Nginx系列(10)- Nginx配置文件详解

    nginx文件结构 ... #全局块 events { #events块 ... } http #http块 { ... #http全局块 server #server块 { ... #server全 ...

  8. SonarQube汉化

    SonarQube安装后默认是英文,如果不习惯看英文,可以进行汉化,官方提供了汉化插件. 登录后,汉化步骤如下: 需要点击了解风险,不然查询到插件后没有install按钮 搜索Chinese,找到插件 ...

  9. Appium driver常用API

    click driver.find_element implicitly_wait send_keys close quit get_window_size switch_to execute bac ...

  10. join方法个人理解

    首先抛出对join的疑问 如果我有一个a线程,一个b线程 那此时 a.start(); b.start(); a.join(); b.join(); 是否意思是a线程先执行完,然后再执行b线程; 如果 ...