当前位置: 首页 > news >正文

【题解】洛谷 P10083 [GDKOI2024 提高组] 不休陀螺 [思维 + 树状数组 + st 表]

 P10083 [GDKOI2024 提高组] 不休陀螺 - 洛谷 (luogu.com.cn)

首先考虑什么样的 [l,r] 区间是 “无限区间”:

(1)总收益不能是负收益。

(2)打完所有负收益的牌后,保证能打非负收益牌中花费最大的那一张。

(3)每一张负收益牌都能在打完其他负收益牌后打。

转化为公式:

(1)\sum_{i=l}^{r}(b[i]-a[i])\geq 0

(2)E+\sum_{i=l}^{r}(b[i]-a[i])_{[a[i]>b[i]}\geq\sum_{i=l}^{r}max(a[i]_{[a[i]\leq b[i]})

(3)E+\sum_{i=l}^{r}(b[i]-a[i])_{[a[i]>b[i]}-(b[j]-a[j])_{[a[j]>b[j]}\geq a[j]_{[a[j]>b[j]}

化简:E+\sum_{i=l}^{r}(b[i]-a[i])_{[a[i]>b[i]}\geq \sum_{j=l}^{r}max(b[j]_{[a[j]>b[j]})

我们发现 (2)  (3) 是比较特殊的。

(以下文段请区分递增与严格递增,递减与严格递减

假设固定左端点 l,右端点 r 不断往右移动,如果当前 r 不满足 2 和 3 的性质,

由于 \sum_{i=l}^{r}(b[i]-a[i])_{[a[i]>b[i]} 是递减的,\sum_{i=l}^{r}max(a[i])_{[a[i]\leq b[i]} 和 \sum_{j=l}^{r}max(b[j]_{[a[j]>b[j]}) 是递增的。

所以之后再右边的 r 就更不可能是答案,即每个 l 最右边的 r 是可以线性增加确定的

确定了 r 后,把 [l,r] 间以 l 为左端点,负收益的右区间点减掉,就是当前 l 的答案。

假设 l=l'+1l' 对应的最右区间是 r',那么 l 对应的 r 肯定大于等于 r'

因为随着 l 的增长,\sum_{i=l}^{r}(b[i]-a[i])_{[a[i]>b[i]} 是递增的,约束条件更宽松。

之前满足条件的右区间点肯定还满足条件,所以 r 只增不减

这很像双指针,我们考虑枚举 lr 继承上一个 l'

r 边增加、边看看是否满足 (2)  (3),不满足立刻退出。

可以先定义一个数组 c[i]=b[i]-a[i] 边移动指针边计算 \sum

\sum_{i=l}^{r}max(a[i])_{[a[i]\leq b[i]} 和 \sum_{j=l}^{r}max(b[j]_{[a[j]>b[j]}) 可以用 st 表,

由于 \geq 号前面的都是 \sum,所以只开一个 st 表,根据 a[i],b[i] 的大小关系放进去 a[i] 或者 b[i]

判断负收益区间点可以用树状数组,每移动 r 一下就把当前 sum_c[r] 放进去,

退出循环时减掉树状数组上比 sum_c[l] 小的点,就是答案。

代码:

#include<bits/stdc++.h>
using namespace std;typedef long long LL;
const int N = 1e6 + 50;int n; LL E;
LL a[N], b[N];
LL c[N], sum_c[N], st[N][30];
LL tr_d[N];
LL cc[N];
map<LL, int> mp;void add(int x, LL d) {if (x == 0) {return ;}for (; x <= n; x += x & -x) {tr_d[x] += d;}
}LL get_sum(int x) {LL res = 0;for (; x >= 1; x -= x & -x) {res += tr_d[x];}return res;
}LL get_mx(int l, int r) {int lg = log2(r - l + 1);return max(st[l][lg], st[r - (1 << lg) + 1][lg]);
}void init_st_tree() {for (int i = 1; i <= n; i ++) {st[i][0] = (a[i] <= b[i]) ? a[i]: b[i];}for (int j = 1; j <= log2(n); j ++) {for (int i = 1; i + (1 << (j - 1)) <= n; i ++) {st[i][j] = max(st[i][j - 1], st[i + (1 << (j - 1))][j - 1]);}}memset(tr_d, 0, sizeof(tr_d));for (int i = 0; i <= n; i ++) {cc[i] = sum_c[i];}sort (cc, cc + n + 1);int nn = unique(cc, cc + n + 1) - cc - 1;for (int i = 0; i <= nn; i ++) {    // 离散化,方便树状数组 mp[cc[i]] = i + 1;    // + 1 防止下标为 0}
}int main () {freopen("top.in", "r", stdin);freopen("top.out", "w", stdout);ios::sync_with_stdio(false);cin.tie(0);cin >> n >> E;for (int i = 1; i <= n; i ++) {cin >> a[i];}for (int i = 1; i <= n; i ++) {cin >> b[i];}sum_c[0] = 0;for (int i = 1; i <= n; i ++) {c[i] = b[i] - a[i];sum_c[i] = sum_c[i - 1] + c[i];}init_st_tree();int r = 1;LL ans = 0;LL sum = 0;     // 负收益总和 for (int l = 1; l <= n; l ++) {while (r <= n) {LL t = get_mx(l, r);if (E + sum + min(0ll, c[r]) >= t) {if (c[r] < 0) {sum += c[r];}add(mp[sum_c[r]], 1);r ++;}else {break;}}int xx = mp[sum_c[l - 1]] - 1;    // 小于 sum_c[l - 1] 的(负收益段)LL tt = get_sum(xx);ans += (r - l) - tt;  // 最右区间应该是 r - 1 if (r == l) {r = l + 1;     // 预备下一个 }else {if (c[l] < 0) {sum -= c[l];}add(mp[sum_c[l]], -1);}}cout << ans << "\n";return 0;
}

http://www.dtcms.com/a/569841.html

相关文章:

  • C语言字符串操作:手写strlen+常用库函数解析
  • 自己可以创建公司网站吗赣州网站制作培训
  • 百度优化排名软件seo交流
  • 链表相关的算法题(1)
  • 速成网站建设有哪些专业做饰品的网站app
  • 服务器负载过高的多维度诊断与性能瓶颈定位指南
  • 超云发布R2425存储服务器:以全栈自研引领国产存储新方向
  • 网站域名快速备案做网站没有高清图片怎么办
  • 【Python基础】f-string用法
  • 前端高频面试手写题——扁平化数组转树
  • 网站建设合同通用范本免费推广引流怎么做
  • 上海怎么建设网站网站建设网站制作公司
  • Flink 多流转换
  • Redis_5_单线程模型
  • 做简单网站用什么软件有哪些洛阳网站建设设计公司
  • CTF WEB入门 命令执行篇29-49
  • IDEA自定义类注释、方法注释
  • Grafana12安装部署[特殊字符]
  • 网站建设报价流程河南建设工程信息网站
  • 苍穹外卖(第五天)
  • NFC与RFID防伪标签:构筑产品信任的科技防线
  • 深圳网站建设 设计首选成都展示型网页设计公司
  • 网站三层结构示意图网站建设资讯
  • WithAnyone: Towards Controllable and ID Consistent Image Generation论文阅读
  • 无人机远距离无线通信模块:突破空中通信的未来之钥
  • IDEA:2020.1 下面有四个小版本:2020.1.1 -- 2020.1.4,哪个与Windows7 更兼容
  • 长春建站网站模板网站仿站
  • 【ROS2+相机】在Ubuntu安装realsense-ros
  • 基于B/S架构的物资管理系统的设计与实现(源码+论文+部署+安装)
  • 告别扫描仪!AI一键PBR材质