题目传送门:LOJ #2567

题意简述:

有 \(n\) 个位置,第 \(i\) 个位置可以填在 \([a_i,b_i]\) (\(1\le a_i\le b_i\le 10^9\))之间的整数,也可以填 \(0\)。

如果第 \(i\) 个位置填了非 \(0\) 的数,则这个数必须大于之前所有位置(\(1\) 到 \(i-1\) 的位置)上的数。

至少要有一个位置填上非 \(0\) 的数。问最终有几种填数方案,两种填数方案不同当且仅当某个位置上填的数不同。

题解:

要求即为选出一些位置填数,并且形成严格递增序列。

发现把所有区间离散化,可以组成 \(\mathcal{O}(n)\) 个连续段,每个连续段中的数的性质是相同的。

因为 \(n\) 不大(只有 \(500\)),考虑 DP。令 \(\mathrm{f}[i][j]\) 表示前 \(i\) 个位置,第 \(i\) 个位置填了在段 \(j\) 中的数的方案数。

显然若 \([a_i,b_i]\) 不包含段 \(j\),则 \(\mathrm{f}[i][j]=0\)。对于其他的情况,考虑如何转移,假设上一个填了在小于 \(j\) 的段中的数的位置是 \(k\),则有 \(\mathrm{f}[i][j]\) 从 \(\mathrm{f}[k][j']\) 转移,其中 \(0\le k<i\) 且 \(1\le j'<j\)。

转移的具体形式是:假设位置 \((k,i]\) 中一共有 \(pos\) 个位置(包括 \(i\) 本身)包含段 \(j\),而段 \(j\) 的长度为 \(len\),则 \(\mathrm{f}[k][j']\) 贡献 \(\displaystyle\sum_{x=1}^{pos}\binom{pos-1}{x-1}\binom{len}{x}\) 倍给 \(\mathrm{f}[i][j]\)。这是因为我们枚举 \(pos\) 个位置中填了 \(x\) 个位置,但是第 \(i\) 个位置必须填,所以乘上 \(\displaystyle\binom{pos-1}{x-1}\),然后 \(len\) 个可行数中选出 \(x\) 个从小到大依次填入,所以再乘上 \(\displaystyle\binom{len}{x}\)。化简一下系数:\(\displaystyle\sum_{x=1}^{pos}\binom{pos-1}{x-1}\binom{len}{x}=\sum_{x}\binom{len}{x}\binom{pos-1}{pos-x}=\binom{len+pos-1}{pos}\)。式子可以这样理解:枚举 \(x\),从 \(len\) 个数中选出 \(x\) 个数,再从 \(pos-1\) 个数中选出 \(pos-x\) 个数,这与直接从 \(len+pos-1\) 个数中选出 \(pos\) 个数等价。

那么我们有 \(\displaystyle\mathrm{f}[i][j]=\sum_{k=0}^{i-1}\binom{len+pos-1}{pos}\sum_{j'=0}^{j-1}\mathrm{f}[k][j']\)。边界是 \(\mathrm{f}[0][0]=1\)、\(\mathrm{f}[0][j]=0\)(\(1\le j\))和 \(\mathrm{f}[i][0]=0\)(\(1\le i\))。

再利用前缀和优化,把第二维做前缀和,把转移变成 \(\mathcal{O}(n)\) 的就好了,转移内的组合数可以 \(\mathcal{O}(n)\) 预处理。

还可以滚动数组一下,空间就是 \(\mathcal{O}(n)\) 的了,不过没必要。

#include <cstdio>
#include <algorithm> typedef long long LL;
const int Mod = 1000000007;
const int MN = 505; int N, lb[MN], rb[MN], lp[MN * 2], len[MN * 2], cnt;
int Inv[MN], C[MN], f[MN], Ans; int main() {
scanf("%d", &N);
for (int i = 1; i <= N; ++i)
scanf("%d%d", &lb[i], &rb[i]),
lp[++cnt] = lb[i],
lp[++cnt] = rb[i] + 1;
std::sort(lp + 1, lp + cnt + 1);
cnt = std::unique(lp + 1, lp + cnt + 1) - lp - 2;
for (int i = 1; i <= cnt; ++i) len[i] = lp[i + 1] - lp[i];
for (int i = 1; i <= N; ++i)
lb[i] = std::lower_bound(lp + 1, lp + cnt + 1, lb[i]) - lp,
rb[i] = std::lower_bound(lp + 1, lp + cnt + 1, rb[i] + 1) - lp - 1;
Inv[1] = 1, C[0] = 1, f[0] = 1;
for (int i = 2; i <= N; ++i) Inv[i] = (LL)(Mod - Mod / i) * Inv[Mod % i] % Mod;
for (int i = 1; i <= cnt; ++i) {
int l = len[i];
for (int j = 1; j <= N; ++j)
C[j] = (LL)C[j - 1] * (l + j - 1) % Mod * Inv[j] % Mod;
for (int j = N; j >= 1; --j) if (lb[j] <= i && i <= rb[j]) {
for (int k = j, a = 0; k >= 1; --k) {
if (lb[k] <= i && i <= rb[k]) ++a;
f[j] = (f[j] + (LL)f[k - 1] * C[a]) % Mod;
}
}
}
for (int i = 1; i <= N; ++i) Ans = (Ans + f[i]) % Mod;
printf("%d\n", Ans);
return 0;
}

LOJ 2567: 洛谷 P3643: bzoj 4584: 「APIO2016」划艇的更多相关文章

  1. LOJ 2085: 洛谷 P1587: bzoj 4652: 「NOI2016」循环之美

    题目传送门:LOJ #2085. 两个月之前做的傻题,还是有必要补一下博客. 题意简述: 求分子为不超过 \(n\) 的正整数,分母为不超过 \(m\) 的正整数的所有互不相等的分数中,有多少在 \( ...

  2. LOJ 2249: 洛谷 P2305: bzoj 3672: 「NOI2014」购票

    题目传送门:LOJ #2249. 题意简述: 有一棵以 \(1\) 号节点为根节点的带边权的树. 除了 \(1\) 号节点的所有节点上都有人需要坐车到达 \(1\) 号节点. 除了 \(1\) 号节点 ...

  3. 洛谷 8 月月赛 & 「PMOI」Round · 04

    T1 T166167 「PMOI-4」人赢 题目大意 给一个数列的前两项分别为\(n\)和\(m\) 当\(i\geq3\)时\(a_i = a_{i-1}*a_{i-2}\)的个位 给定\(n\), ...

  4. 【LOJ】#2567. 「APIO2016」划艇

    题解 显然有个很暴力的dp,\(dp[i][j]\)表示选到第\(i\)个数,末尾的数是\(j\)的方案数 但是第二维就开不下了,怎么办呢 考虑离散化整个区间,我们记录\(dp[i][j][k]\)表 ...

  5. Loj #2568. 「APIO2016」烟花表演

    Loj #2568. 「APIO2016」烟花表演 题目描述 烟花表演是最引人注目的节日活动之一.在表演中,所有的烟花必须同时爆炸.为了确保安全,烟花被安置在远离开关的位置上,通过一些导火索与开关相连 ...

  6. 「APIO2016」烟花表演

    「APIO2016」烟花表演 解题思路 又是一道 solpe trick 题,观察出图像变化后不找一些性质还是挺难做的. 首先令 \(dp[u][i]\) 为节点 \(u\) 极其子树所有叶子到 \( ...

  7. LOJ 2743(洛谷 4365) 「九省联考 2018」秘密袭击——整体DP+插值思想

    题目:https://loj.ac/problem/2473 https://www.luogu.org/problemnew/show/P4365 参考:https://blog.csdn.net/ ...

  8. 洛谷 P5206: bzoj 5475: LOJ 2983: [WC2019] 数树

    一道技巧性非常强的计数题,历年WC出得最好(同时可能是比较简单)的题目之一. 题目传送门:洛谷P5206. 题意简述: 给定 \(n, y\). 一张图有 \(|V| = n\) 个点.对于两棵树 \ ...

  9. Solution -「APIO 2016」「洛谷 P3643」划艇

    \(\mathcal{Description}\)   Link & 双倍经验.   给定 \(n\) 个区间 \([a_i,b_i)\)(注意原题是闭区间,这里只为方便后文描述),求 \(\ ...

随机推荐

  1. QAU 17校赛 J题 剪丝带(完全背包变形)

    题意: 剪一段丝带,对于剪完后的每一段丝带长度必须是a,b,c 输入丝带的长度  n 和  a  b  c 输出一个整数,代表最多能剪成多少段 样例输入 5 5 3 2 7 5 5 2 样例输出 2 ...

  2. MT【27】对数方程组求范围

    解答:3 评论:此类题目通性通法为换元后化归为线性规划问题.当然不等式凑配也是常见技巧,只是容易范围扩大或者缩小.

  3. 2.9 C++使用默认参数的构造函数

    总结: 默认参数的构造函数,其默认参数必须置于参数列表的结尾. 设计类的构造函数的时候最好不要同时是用构造函数的重载和带参数的构造函数. 我们可以想象一个这样的场景:某一天书店整理库存,发现了一些非常 ...

  4. Java编程,打印昨天的当前时刻

    public class Demo {  /*  * Java编程,打印昨天的当前时刻  */ public static void main(String[] args){  Calendar ca ...

  5. BZOJ 4785 [Zjoi2017]树状数组 | 二维线段树

    题目链接 BZOJ 4785 题解 这道题真是令人头秃 = = 可以看出题面中的九条可怜把求前缀和写成了求后缀和,然后他求的区间和却仍然是sum[r] ^ sum[l - 1],实际上求的是闭区间[l ...

  6. 【转】CPU上下文切换的次数和时间(context switch)

    http://iamzhongyong.iteye.com/blog/1895728 什么是CPU上下文切换? 现在linux是大多基于抢占式,CPU给每个任务一定的服务时间,当时间片轮转的时候,需要 ...

  7. suoi38 卖XY序列 (贪心+前缀和)

    因为只能带一个,买卖价格又一样,所以只要右边的比左边的大,就从这买下来然后带到下一个卖掉就行了(我想到别处再卖的话大不了再重新买回来嘛) 所以给max(w[i]-w[i-1],0)维护一个前缀和就行了 ...

  8. [学习笔记]prufer序列

    前言 PKUWC和NOIWC都考察了prufer序列,结果统统爆零 prufer序列就是有标号生成树对序列的映射 prufer序列生成 每次选择编号最小的叶子删掉,把叶子的父亲加入prufer序列,直 ...

  9. ASP.NET MVC 网站优化之压缩技术

    压缩 html 可以去除代码中无用的空格等,这样可提高网站的加载速度并节省带宽. 实现 ActionFilter 来完成 html 的压缩 public class WhitespaceFilterA ...

  10. ReactNative系列组件用法(一)

    首先我们来认识view 改变一些特性,再来看看项目的变化 我们新增flex布局的一些属性,再来看看项目的变化 接下来我们来看看如果获取屏幕的分辨率 关于图片的用法,reactNative这里也是很神奇 ...