[Luogu P3643] [BZOJ 4584] [LOJ 2567] [APIO2016]划艇

洛谷传送门
BZOJ传送门
LOJ传送门

题目描述

在首尔城中,汉江横贯东西。在汉江的北岸,从西向东星星点点地分布着 N N N 个划艇学校,编号依次为 1 1 1 N N N。每个学校都拥有若干艘划艇。同一所学校的所有划艇颜色相同,不同的学校的划艇颜色互不相同。颜色相同的划艇被认为是一样的。每个学校可以选择派出一些划艇参加节日的庆典,也可以选择不派出任何划艇参加。如果编号为 i i i 的学校选择派出划艇参加庆典,那么,派出的划艇数量可以在 a i a_i ai b i b_i bi 之间任意选择( a i ≤ b i a_i \leq b_i aibi)。

值得注意的是,编号为 i i i 的学校如果选择派出划艇参加庆典,那么它派出的划艇数量必须大于任意一所编号小于它的学校派出的划艇数量。

输入所有学校的 a i , b i a_i,b_i ai,bi 的值,求出参加庆典的划艇有多少种可能的情况,必须有至少一艘划艇参加庆典。两种情况不同当且仅当有参加庆典的某种颜色的划艇数量不同。

输入输出格式

输入格式:

第一行包括一个整数 N N N,表示学校的数量。

接下来 N N N 行,每行包括两个正整数,用来描述一所学校。其中第 $i $行包括的两个正整数分别表示 a i , b i a_i,b_i ai,bi 1 ≤ a i ≤ b i ≤ 1 0 9 1 \leq a_i \leq b_i \leq 10^9 1aibi109)。

输出格式:

输出一行,一个整数,表示所有可能的派出划艇的方案数除以 1 , 000 , 000 , 007 1,000,000,007 1,000,000,007 得到的余数。

输入输出样例

输入样例#1:
2
1 2
2 3
输出样例#1:
7

说明

【样例解释】

在只有一所学校派出划艇的情况下有 4 4 4 种方案,两所学校都派出划艇的情况下有 3 3 3 种方案,所以答案为 7 7 7

【数据范围】

子任务 1 1 1 9 9 9 分): 1 ≤ N ≤ 500 1 \leq N \leq 500 1N500 且对于所有的 1 ≤ i ≤ N 1 \leq i \leq N 1iN,保证 a i = b i a_i=b_i ai=bi

子任务 2 2 2 22 22 22 分): 1 ≤ N ≤ 500 1 \leq N \leq 500 1N500 ∑ i = 1 N ( b i − a i ) ≤ 1 0 6 \sum_{i=1}^N (b_i-a_i) \leq 10^6 i=1N(biai)106

子任务 3 3 3 27 27 27 分): 1 ≤ N ≤ 100 1 \leq N \leq 100 1N100

子任务 4 4 4 42 42 42 分): 1 ≤ N ≤ 500 1 \leq N \leq 500 1N500

解题分析

P K U W C   D a y 2 T 1   S u b t a s k 2 PKUWC\ Day2T1\ Subtask2 PKUWC Day2T1 Subtask2来填坑了…

首先有个复杂度很不对的 d p dp dp d p [ i ] [ j ] dp[i][j] dp[i][j]表示第 i i i个学校派出 j j j艘赛艇的方案数。

然后我们注意到虽然区间很大, 但学校数不多, 所以可以离散化出这些区间, 可以设 d p [ i ] [ j ] [ k ] dp[i][j][k] dp[i][j][k]表示考虑到第 i i i个学校, 其在第 j j j块选到了第 k k k个位置的方案数。

但我们发现只要记录了选到哪个位置, d p dp dp复杂度就不太对。 所以直接设 d p [ i ] [ j ] [ k ] dp[i][j][k] dp[i][j][k]表示考虑到第 i i i个点, 其派出的赛艇数量在第 j j j块, 且数量在第 j j j块的学校总共有 k k k个的学校的组成不同的方案数。 换句话说, 我们现在不关心具体放在哪里了, 只关心有哪些学校在这一块里。 这样的话因为每次考虑加入新学校后是和前面的方案完全不同的, 直接一个组合数就可以统计出贡献。

然后我们发现第 i i i个学校可以从 i − 1 , i − 2 , . . . , 1 i-1,i-2,...,1 i1,i2,...,1个学校对应块的状态转移过来, 直接一个前缀和优化就好了。

代码如下:

#include <cstdio>
#include <cstring>
#include <cctype>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#define R register
#define IN inline
#define W while
#define MX 1005
#define MOD 1000000007
#define gc getchar()
#define ll long long
template <class T>
IN void in(T &x)
{
	x = 0; R char c = gc;
	for (; !isdigit(c); c = gc);
	for (;  isdigit(c); c = gc)
	x = (x << 1) + (x << 3) + c - 48;
}
int n, ans, dif;
int pos[MX], sum[MX][MX], f[MX][MX], inv[MX], lef[MX], rig[MX], pre[MX];
int main(void)
{
	in(n);
	for (R int i = 1; i <= n; ++i)
	{
		in(lef[i]), in(rig[i]);
		pos[++dif] = lef[i] - 1;
		pos[++dif] = rig[i];
	}
	inv[0] = inv[1] = 1;
	for (R int i = 2; i <= n; ++i) inv[i] = 1ll * inv[MOD % i] * (MOD - MOD / i) % MOD;
	std::sort(pos + 1, pos + 1 + dif);
	dif = std::unique(pos + 1, pos + 1 + dif) - pos - 1;
	for (R int i = 2; i <= dif; ++i)
	{
		int len = pos[i] - pos[i - 1];
		f[i][0] = 1;
		for (R int j = 1; j <= n; ++j)
		f[i][j] = 1ll * f[i][j - 1] * inv[j] % MOD * (len - j + 1) % MOD;
	}
	int ans = 0;
	for (R int i = 1; i <= n; ++i)
	{
		int s = 1;//start from current point
		for (R int j = 2; j <= dif; ++j)
		{
			int tmp = s; (s += pre[j]) %= MOD;
			if (lef[i] <= pos[j - 1] + 1 && rig[i] >= pos[j])
			{
				for (R int k = i - 1; k; --k)
				{
					(sum[j][k + 1] += sum[j][k]) %= MOD;
					(ans += 1ll * sum[j][k] * f[j][k + 1] % MOD) %= MOD;
					(pre[j] += 1ll * sum[j][k] * f[j][k + 1] % MOD) %= MOD;
				}
				(ans += 1ll * tmp * (pos[j] - pos[j - 1]) % MOD) %= MOD;
				(pre[j] += 1ll * tmp * (pos[j] - pos[j - 1]) % MOD) %= MOD;
				(sum[j][1] += tmp) %= MOD;
			}
		}
	}
	printf("%d", ans);
}

CCF大数据与计算智能大赛-面向电信行业存量用户的智能套餐个性化匹配模型联通赛-复赛第二名-【多分类,embedding】.zip项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值