JZOJ5922. 【NOIP2018模拟10.23】sequence

12 篇文章 0 订阅
2 篇文章 0 订阅

题意:

小 F 是一位 Hack 国的居民,他生活在一条长度为 n 的街道上,这个街道上总共有 n 个商店。每个商店里售卖着不同的 Hack 技能包,每个商店本身也会有个便利值。初始时,每个商店的便利值均为 0。每一天,街道上都会有一些商店优化改造。
具体来说,对于每一天,优化改造的商店都是一个连续的区间 l ∼ r,每次优化改造也会有一个优化参数 k。对于所有 l ≤ i ≤ r ,第 i 个商店的便利值会增加

小 F 想知道,m 天之后,每个商店的便利值分别是多少。由于小 F 并不喜欢高精度,因此你只需要输出便利值对 10^9 + 7 取模的结果。

数据范围:

Analysis:

可以根据杨辉三角的递推式: C i j = C i − 1 j − 1 + C i j − 1 C_i^j=C_{i-1}^{j-1}+C_i^{j-1} Cij=Ci1j1+Cij1
发现这个东西可以分为 k k k层逐层做,每一次相当于做一次前缀和。我们搞一个差分把区间边界的影响消掉,发现他们 k k k是不同的,这样很难做,某一部分重复算。考虑对于每一个 k k k做一次,复杂度 O ( n k 2 ) O(nk^2) O(nk2)。或者我们从高往低做,让他顶住最下面。复杂度: O ( n k ) O(nk) O(nk)

Code:

# include<cstdio>
# include<cstring>
# include<algorithm>
using namespace std;
const int N = 6e5 + 5;
const int mo = 1e9 + 7;
typedef long long ll;
int inv[N],fac[N],fac_[N],tag[N][25];
int n,m;
inline int read()
{
	int x = 0; char ch = getchar();
	for (; ch < '0' || ch > '9' ; ch = getchar());
	for (; ch >= '0' && ch <= '9' ; ch = getchar()) x = x * 10 + ch - '0';
	return x;
}
inline int inc(int x,int y) { return x + y >= mo ? x + y - mo : x + y; }
inline int dec(int x,int y) { return x - y < 0 ? x - y + mo : x - y; }
inline int C(int n,int m) { return (ll)fac[n] * fac_[m] % mo * fac_[n - m] % mo; }
int main()
{
	freopen("sequence.in","r",stdin);
	freopen("sequence.out","w",stdout);
	n = read(),m = read(); fac[0] = fac_[0] = inv[1] = 1;
	for (int i = 1 ; i <= n + 20 ; ++i)
	{
		if (i > 1) inv[i] = (ll)(mo - mo / i) * inv[mo % i] % mo;
		fac[i] = (ll)fac[i - 1] * i % mo,fac_[i] = (ll)fac_[i - 1] * inv[i] % mo;
	}
	for (int i = 1 ; i <= m ; ++i)
	{
		int l = read(),r = read(),k = read();
		++tag[l][k + 1],tag[r + 1][k + 1] = dec(tag[r + 1][k + 1],1);
		for (int j = k ; j ; --j) tag[r + 1][j] = dec(tag[r + 1][j],C(r - l + k - j + 1,k - j + 1));
	}
	for (int j = 21 ; j ; --j)
		for (int i = 1 ; i <= n ; ++i) tag[i][j] = inc(tag[i][j],inc(tag[i][j + 1],tag[i - 1][j]));
	for (int i = 1 ; i <= n ; ++i) printf("%d\n",tag[i][1]);
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值