题意是,有$n$个石头,每个石头有初始能量$E_i$,每秒能量增长$L_i$,以及能量上限$C_i$,有$m$个收能量的时间点,每次把区间$\left[S_i, T_i\right]$石头的能量都给收掉,石头的能量都置零重新开始增长。问最后收了多少能量。

看完题解觉得好有道理...我好菜...
考虑每个石头在多少个时间点收能量,然后每次收的能量就和这些时间点的时间间隔有关。
若时间间隔大于等于$\dfrac {C_i}{L_i}$,那么这一段对答案的贡献就是$C_i$了,统计有多少这样的段即可。
若时间间隔小于$\dfrac {C_i}{L_i}$那么对答案的贡献就是时间长度$t \times L_i$。
用两个权值树状数组可以维护对应时间长度的和及个数。
时间点可以用set维护。从前到后遍历,遇到一个$S_i$就把对应是时间加入,遇到一个$T_i + 1$就把时间删去,同时维护树状数组即可。感觉看代码就很好懂?

#include <bits/stdc++.h>
#define ll long long
using namespace std; const int N = 2e5 + ;
int n, m;
ll E[N], C[N], L[N];
set<int> st;
vector<int> G[N]; struct BIT {
ll tree1[N], tree2[N];
inline void clear() {
memset(tree1, , sizeof tree1);
memset(tree2, , sizeof tree2);
}
inline int lowbit(int x) {
return x & -x;
}
inline void add(int x, int val) {
if (!x) return;
for (int i = x; i < N; i += lowbit(i)) {
if (val > ) tree1[i]++;
else tree1[i]--;
tree2[i] += val;
}
}
inline int query1(int x) {
int ans = ;
for (int i = x; i; i -= lowbit(i))
ans += tree1[i];
return ans;
}
inline int query2(int x) {
int ans = ;
for (int i = x; i; i -= lowbit(i))
ans += tree2[i];
return ans;
}
} bit; inline void init() {
st.clear();
bit.clear();
for (int i = ; i <= n; i++) G[i].clear();
} void add(int x) {
if (st.empty()) {
st.insert(x);
return;
}
auto p = st.lower_bound(x);
if (p == st.begin()) {
bit.add((*p - x), (*p - x));
st.insert(x);
return;
}
if (p == st.end()) {
bit.add(x - (*prev(p)), x - (*prev(p)));
st.insert(x);
return;
}
int x1 = (*p) - x, x2 = x - (*prev(p));
bit.add(x1, x1);
bit.add(x2, x2);
bit.add(x1 + x2, -x1 - x2);
st.insert(x);
} void del(int x) {
auto p = st.find(x);
if (st.size() == ) {
st.erase(p);
return;
}
if (p == st.begin()) {
bit.add((*next(p)) - x, x -(*next(p)));
st.erase(p);
return;
}
if (p == prev(st.end())) {
bit.add(x - (*prev(p)), (*prev(p)) - x);
st.erase(p);
return;
}
int x1 = (*next(p)) - x, x2 = x - (*prev(p));
bit.add(x1, -x1);
bit.add(x2, -x2);
bit.add(x1 + x2, x1 + x2);
st.erase(p);
} int main() {
int T, kase = ;
scanf("%d", &T);
while (T--) {
scanf("%d", &n);
init();
for (int i = ; i <= n; i++)
scanf("%lld%lld%lld", &E[i], &L[i], &C[i]);
scanf("%d", &m);
for (int i = ; i <= m; i++) {
int l, r, t;
scanf("%d%d%d", &t, &l, &r);
G[l].push_back(t); G[r + ].push_back(-t);
}
ll ans = ;
for (int i = ; i <= n; i++) {
for (auto x: G[i]) {
if (x > ) add(x);
else del(-x);
}
if (st.empty()) continue;
ans += min(C[i], 1LL * (*st.begin()) * L[i] + E[i]);
if (!L[i]) continue;
ans += (st.size() - - bit.query1(C[i] / L[i])) * C[i] + bit.query2(C[i] / L[i]) * L[i];
}
printf("Case #%d: %lld\n", ++kase, ans);
}
return ;
}

F Energy stones的更多相关文章

  1. 2019牛客多校第七场 F Energy stones 树状数组+算贡献转化模拟

    Energy stones 题意 有n块石头,每块有初始能量E[i],每秒石头会增长能量L[i],石头的能量上限是C[i],现有m次时刻,每次会把[s[i],t[i]]的石头的能量吸干,问最后得到了多 ...

  2. Kick Start 2019 Round B Energy Stones

    对我很有启发的一道题. 这道题的解法中最有思维难度的 observation 是 For simplicity, we will assume that we never eat a stone wi ...

  3. 2019牛客暑期多校训练营(第七场)E F H I

    E Find the median 题意:每次往序列中增加连续的[l,r]的数,每加入一次就询问当前序列的中位数. 解法:此题没有要求在线,那么直接离线+线段树+二分就可以了.求出每个端点之后排序得到 ...

  4. 2019nc#7

    题号 标题 已通过代码 题解/讨论 通过率 团队的状态 A String 点击查看 进入讨论 566/3539  通过 B Irreducible Polynomial 点击查看 规律 730/229 ...

  5. 2019牛客多校 Round7

    Solved:5 Rank:296 E Find the median (线段树) 题意:最开始一个空的数组 4e5次操作 每次把Li,Ri中的每个数插入进来 问当前的中位数 题解:把这n个区间离散化 ...

  6. ZJUT11 多校赛补题记录

    牛客第一场 (通过)Integration (https://ac.nowcoder.com/acm/contest/881/B) (未补)Euclidean Distance (https://ac ...

  7. hdu 3681 Prison Break(状态压缩+bfs)

    Problem Description Rompire . Now it’s time to escape, but Micheal# needs an optimal plan and he con ...

  8. 过河(DP)

    问题描述] 在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳到另一侧.在桥上有一些石子,青蛙很讨厌踩在这些石子上.由于桥的长度和青蛙一次跳过的距离都是正整数,我们可以把独木桥上青蛙可能到达的点看成 ...

  9. 【模拟】bzoj1686: [Usaco2005 Open]Waves 波纹

    打完模拟题来庆祝一波:):感觉最近陷入一种“口胡五分钟打题两小时”的巨坑之中…… Description Input     第1行:四个用空格隔开的整数Pj Bi,B2,R. P(1≤P≤5)表示石 ...

随机推荐

  1. 螺旋折线-C++

    标题:螺旋折线 如图p1.png所示的螺旋折线经过平面上所有整点恰好一次. 对于整点(X, Y),我们定义它到原点的距离dis(X, Y)是从原点到(X, Y)的螺旋折线段的长度. 例如dis(0, ...

  2. teacher笔记

    ======= 总览 start ======= 1.素质教育以提高国民素质为根本宗旨4.素质教育是促进学生个性发展的教育5.素质教育是以培养学生的创新精神和事件能力为重点的教育2.素质教育是面向全体 ...

  3. Implementing Azure AD Single Sign-Out in ASP.NET Core(转载)

    Let's start with a scenario. Bob the user has logged in to your ASP.NET Core application through Azu ...

  4. HashMap源码原理

    HashMap源码解析(负载因子,树化策略,内部hash实现,resize策略) 内部属性: 负载因子: final float loadFactor(默认为0.75f) 实际容量: int thre ...

  5. c#高效准确的条形码、线性条码、QR二维码读写类库-SharpBarcode介绍

    SharpBarcode是一款支持.NET(C#,VB)的高效易用的条形码.QR二维码的读取和生成类库. 主要功能: 1.支持几乎所有常见类型的线性条形码和QR二维码的读取,高效读取,准确率高. 2. ...

  6. APS.NET MVC + EF (00)---C#基础

    命名参数 命名参数是把参数附上参数名称,这样在调用方法的时候不必按照原来的参数顺序填写参数,只需要对应好参数的名称也能完成方法调用. static void Main(string[] args) { ...

  7. Eclipse集成Git做团队开发:分支管理

    在日常开发工作中,我们通常使用版本控制软件管理团队的源代码,常用的SVN.Git.与SVN相比,Git有分支的概念,可以从主分支创建开发分支,在开发分支测试没有问题之后,再合并到主分支上去,从而避免了 ...

  8. Java基础篇(下)

    6.Java面向对象的三个特征与含义 三大特征是:继承.封装和多态. (1)继承的概念 继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类. 继承就是子类继承父类的特征和行为,使得 ...

  9. python基础03--int,bool,str

    1.1 数字int 1.i = 100  i.bit_length()   转化为二进制的最小位数 1.2 布尔 bool 1.True  False      0是False 1.3 数据转换    ...

  10. MySQL基础-1

    目录 数据库的基本概念 什么是数据库 为什么要使用数据库 数据库的分类 数据库的重要概念 数据库的安装 安装步骤 简单使用数据库 数据库的基本概念 什么是数据库 字面意思数据库就是存储数据的仓库,正常 ...