Educational Codeforces Round 69 (Rated for Div. 2) E. Culture Code

题目链接

题意:

给出\(n\)个俄罗斯套娃,每个套娃都有一个\(in_i,out_i\),并满足\(out_i>in_i\)。定义套娃\(i\)能套在套娃\(j\)里面,当且仅当\(out_i\leq in_j\)。

定义极大套娃组:当且仅当不能有另外一个套娃套在它们身上。

定义套娃组额外空间为\(in_1+(in_2-out_1)+\cdots +(in_k-out_{k-1})\),其中\(k\)为最大的那个套娃。

现在求额外空间最小的极大套娃组都多少个。

思路:

将上面求和式子变换一下有:

\[in_k+\sum_{i=1}^{k-1}in_i-out_i
\]

分析这个式子,也就是对于一个在最外面的套娃\(k\)来说,其余里面套娃的贡献就为\(in_i-out_i\),是独立的。

首先将所有套娃按\(in\)升序排序,之后依次枚举每一个套娃并将其视作最后一个套娃。假设当前枚举的\(i\),那么\(dp(i)=min_{out_j\leq in_i}\{dp(j)\}+in_i\),\(dp\)中存储的是套娃的贡献值,\(dp(i)\)表示以\(i\)作结尾的套娃最小的额外空间是多少。

因为题目还要求数目,考虑转移的时候在线段树上面查询,同时维护一个\(sum\)记录个数,查询、更新的时候进行结点的合并,合并实现两个功能:一是找最小值,而是更新个数,详见代码即可。

最后统计答案的时候,找到所有的极大套娃组进行统计。

代码如下:

#include <bits/stdc++.h>
#define mp make_pair
#define fi first
#define se second
#define INF 0x3f3f3f3f3f3f3f3f
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int N = 2e5 + 5, MOD = 1e9 + 7;
int n;
pii a[N];
struct SEG{
struct node{
ll Min, sum;
node() {
sum = 0; Min = INF;
}
node(ll Min, ll sum) : Min(Min), sum(sum) {}
node operator + (const node &other) const {
node res = node();
if(Min < other.Min) {
res.Min = Min;
res.sum = sum;
} else if(Min == other.Min) {
res.Min = Min;
res.sum = (other.sum + sum) % MOD;
} else {
res.Min = other.Min;
res.sum = other.sum;
}
return res;
}
}t[N << 3], res;
void build(int o, int l, int r) {
if(l == r) {
t[o] = node();
return;
}
int mid = (l + r) >> 1;
build(o << 1, l, mid); build(o << 1|1, mid + 1, r);
}
void update(int o, int l, int r, int p, node v) {
if(l == r) {
t[o] = t[o] + v;
return ;
}
int mid = (l + r) >> 1;
if(p <= mid) update(o << 1, l, mid, p, v);
else update(o << 1|1, mid + 1, r, p, v);
t[o] = t[o << 1] + t[o << 1|1];
}
void query(int o, int l, int r, int L, int R) {
if(L <= l && r <= R) {
res = res + t[o];
return ;
}
int mid = (l + r) >> 1;
if(L <= mid) query(o << 1, l, mid, L, R);
if(R > mid) query(o << 1|1, mid + 1, r, L, R);
}
}seg;
int D, b[N << 1];
ll c[N], d[N];
int id(int x) {
return lower_bound(b + 1, b + D + 1, x) - b;
}
int main() {
ios::sync_with_stdio(false); cin.tie(0);
cin >> n;
for(int i = 1; i <= n; i++) {
cin >> a[i].se >> a[i].fi;
b[++D] = a[i].fi; b[++D] = a[i].se;
}
sort(a + 1, a + n + 1);
sort(b + 1, b + D + 1);
D = unique(b + 1, b + D + 1) - b - 1;
ll Min = INF;
seg.build(1, 1, D);
for(int i = 1; i <= n; i++) {
seg.res = SEG::node();
seg.query(1, 1, D, 1, id(a[i].fi));
if(seg.res.Min == INF) {
seg.res = SEG::node(a[i].fi - a[i].se, 1);
c[i] = 1; d[i] = a[i].fi;
seg.update(1, 1, D, id(a[i].se), seg.res);
} else {
c[i] = seg.res.sum;
d[i] = seg.res.Min + a[i].fi;
seg.res.Min += a[i].fi - a[i].se;
seg.update(1, 1, D, id(a[i].se), seg.res);
}
if(a[i].se > a[n].fi) Min = min(Min, d[i]);
}
ll ans = 0;
for(int i = 1; i <= n; i++)
if(a[i].se > a[n].fi && d[i] == Min)
ans = (ans + c[i]) % MOD;
cout << ans;
return 0;
}

Educational Codeforces Round 69 (Rated for Div. 2) E. Culture Code的更多相关文章

  1. Educational Codeforces Round 69 (Rated for Div. 2)

                                                                                                  A. DIY ...

  2. Educational Codeforces Round 69 (Rated for Div. 2) D. Yet Another Subarray Problem 背包dp

    D. Yet Another Subarray Problem You are given an array \(a_1, a_2, \dots , a_n\) and two integers \( ...

  3. Educational Codeforces Round 69 (Rated for Div. 2) C. Array Splitting 水题

    C. Array Splitting You are given a sorted array

  4. Educational Codeforces Round 69 (Rated for Div. 2) A~D Sloution

    A. DIY Wooden Ladder 题意:有一些不能切的木板,每个都有一个长度,要做一个梯子,求梯子的最大台阶数 做梯子的木板分为两种,两边的两条木板和中间的若干条台阶木板 台阶数为 $k$ 的 ...

  5. Educational Codeforces Round 69 (Rated for Div. 2)D(DP,思维)

    #include<bits/stdc++.h>using namespace std;int a[300007];long long sum[300007],tmp[300007],mx[ ...

  6. Educational Codeforces Round 69 (Rated for Div. 2) C. Array Splitting (思维)

    题意:给你一个长度为\(n\)的升序序列,将这个序列分成\(k\)段,每一段的值为最大值和最小值的差,求\(k\)段值的最小和. 题解:其实每一段的最大值和最小值的差,其实就是这段元素的差分和,因为是 ...

  7. Educational Codeforces Round 69 (Rated for Div. 2) D. Yet Another Subarray Problem 【数学+分块】

    一.题目 D. Yet Another Subarray Problem 二.分析 公式的推导时参考的洛谷聚聚们的推导 重点是公式的推导,推导出公式后,分块是很容易想的.但是很容易写炸. 1 有些地方 ...

  8. Educational Codeforces Round 60 (Rated for Div. 2) - C. Magic Ship

    Problem   Educational Codeforces Round 60 (Rated for Div. 2) - C. Magic Ship Time Limit: 2000 mSec P ...

  9. Educational Codeforces Round 60 (Rated for Div. 2) - D. Magic Gems(动态规划+矩阵快速幂)

    Problem   Educational Codeforces Round 60 (Rated for Div. 2) - D. Magic Gems Time Limit: 3000 mSec P ...

随机推荐

  1. python对图片批量命名

    深度学习中经常会有批量对图片进行重命名,从网上看到的资料整理一下,方便以后查看. import os class BatchRename(): ''' 批量重命名文件夹中的图片文件 ''' def _ ...

  2. python 在cmd时执行celery -A tasks worker --loglevel=info报错:failed to create process怎么解决

    在cmd命令前加 : python -m 命令(如:python -m celery -A tasks worker --loglevel=info) -m: 将库中的python模块用作脚本去运行, ...

  3. linux alias写快捷键笔记

    linux alias写快捷键笔记<pre>#vi ~/.bashrc ps:~找个代表当前登录用户的用户目录 pwd就知道了alias phpfpmrestart='/usr/local ...

  4. @Import导入自定义选择器

    @Import导入自定义选择器 之前一篇博文:Spring中的@Import注解已经详细介绍了@Import注解,不赘述. 需求描述 通过@import注解自定义组件选择器,将满足我们自定义的规则的b ...

  5. 蚂蚁花呗5面面试真题,你敢来挑战一下吗?(Java岗)

    蚂蚁花呗一面(一个小时): JDK 中有哪几个线程池?顺带把线程池讲了个遍 Java容器有哪些?哪些是同步容器,哪些是并发容器? ArrayList和LinkedList的插入和访问的时间复杂度? j ...

  6. 彻底解决springboot修改页面和代码会自动重启

    3.application.yml配置 spring.devtools.restart.enabled=falsespring.thymeleaf.cache=false 1.解决thymeleaf修 ...

  7. 关于C语言中整数范围的一些解释

    示例代码 #include <stdio.h> int main() { ; printf("%d\n", c); ; printf("%d\n", ...

  8. CSP2019-S游记

    目录 CSP2019-S游记 Day -2(UPDATE:2019-11-14) Day -1(UPDATE:2019-11-15) Day 1(UPDATE:2019-11-16) Day 2(UP ...

  9. Java学习:List接口

    List接口 java.util.list接口 extends Collection接口 List接口的特点: 有序的集合,存储元素和取出元素的顺序是一致的(存储123 取出123) 有索引,包含了一 ...

  10. java中的Date类

    一.Date类简介 日期类主要包括Date类与Calendar类,这一节我们先介绍Date类, Date 表示特定的瞬间,精确到毫秒.Date类用于表示日期和时间,在计算机中的表示和我们现实世界使用差 ...