2019牛客暑期多校训练营(第七场)F Energy stones —— set+树状数组求随时间增长的区间和问题

本文主要是介绍2019牛客暑期多校训练营(第七场)F Energy stones —— set+树状数组求随时间增长的区间和问题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

This way

题意:

有n个石头,这些石头一开始有一些能量e[i],并且每过一个单位的时间会增长l[i],直到有c[i]的能量为止。现在有q个询问
t l r表示在t时刻的时候收割l-r的所有能量,并且将其能量置为0,然后这些石头的能量重新增长。问你最后你收割了多少能量

题解:

for一遍所有的石头,用一个set维护在这个时候有哪些收割的时刻。
每个石头有两种状态:未达到c[i]和已达到c[i]
entir树状数组维护达到c[i]的数量
half树状数组维护未达到c[i]的时间的总和
还需要特判一下第一次收割的情况。
新进来一个时间的时候,它的位置总共可分为三种情况:
1.在最下面
在这里插入图片描述
红色的表示新进来的时间,那么这个时候树状数组就可以加入红色到最下面黑色的值,因为我们是特判第一个位置的来着。
在这里插入图片描述
第二种情况是在中间
在这里插入图片描述
那么就是减掉第三个区间,加上第一个和第二个区间
第三种情况就是在最上面
在这里插入图片描述
这样就只需要在树状数组中加入值即可

代码贼丑,理解了其中的道理之后自己去敲吧

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=1e5+5;
struct Add
{int l;ll y;bool operator< (const Add& a)const{return l<a.l;}
}add[N];
struct Del
{int r;ll y;bool operator< (const Del& a)const{return r<a.r;}
}del[N];
ll e[N],l[N],c[N],half[N*2],entir[N*2];
set<ll>now;
int lowbit(int x){return x&(-x);}
void add_e(int x,int v)
{for(int i=x;i;i-=lowbit(i))entir[i]+=v;
}
ll q_e(int x)
{ll ans=0;for(int i=x;i<N*2;i+=lowbit(i))ans+=entir[i];return ans;
}
void add_h(int x,ll f)
{for(int i=x;i<N*2;i+=lowbit(i))half[i]+=(ll)x*f;
}
ll q_h(int x)
{ll ans=0;for(int i=x;i;i-=lowbit(i))ans+=half[i];return ans;
}
int main()
{int t,cas=0;scanf("%d",&t);while(t--){now.clear();memset(entir,0,sizeof(entir));memset(half,0,sizeof(half));int n;scanf("%d",&n);for(int i=1;i<=n;i++)scanf("%lld%lld%lld",&e[i],&l[i],&c[i]);int q;scanf("%d",&q);for(int i=1;i<=q;i++){int t,x,y;scanf("%d%d%d",&t,&x,&y);add[i].l=x,add[i].y=t;del[i].r=y+1,del[i].y=t;}sort(add+1,add+1+q),sort(del+1,del+1+q);int padd=1,pdel=1;ll ans=0;set<ll>::iterator it,sit;for(int i=1;i<=n;i++){//delwhile(del[pdel].r==i){// printf("%lld\n",j);it=now.find(del[pdel].y);if(it==now.end())continue;sit=it;sit++;if(it==now.begin()){if(sit!=now.end()){int tim=*sit-*it;add_e(tim,-1);add_h(tim,-1);}}else if(sit==now.end()){sit=it;sit--;int tim=*it-*sit;add_e(tim,-1);add_h(tim,-1);}else{int tim=*sit-*it;add_e(tim,-1);add_h(tim,-1);sit--;it--;tim=*sit-*it;add_e(tim,-1);add_h(tim,-1);sit++;tim=*sit-*it;add_e(tim,1);add_h(tim,1);}now.erase(now.find(del[pdel].y));pdel++;}//addwhile(add[padd].l==i){it=now.find(add[padd].y);if(it!=now.end())continue;now.insert(add[padd].y);it=now.find(add[padd].y);sit=it;sit++;if(it==now.begin()){if(sit!=now.end()){int tim=*sit-*it;add_e(tim,1);add_h(tim,1);}}else if(sit==now.end()){sit=it;sit--;int tim=*it-*sit;add_e(tim,1);add_h(tim,1);}else{int tim=*sit-*it;add_e(tim,1);add_h(tim,1);sit--;it--;tim=*sit-*it;add_e(tim,1);add_h(tim,1);sit++;tim=*sit-*it;add_e(tim,-1);add_h(tim,-1);}padd++;}if(!now.empty()){ll sta=*now.begin();if(sta*l[i]+e[i]<=c[i])ans+=sta*l[i]+e[i];elseans+=c[i];if(l[i]!=0){ans+=c[i]*q_e((c[i]+l[i]-1)/l[i]);ans+=l[i]*q_h((c[i]-1)/l[i]);}}}printf("Case #%d: %lld\n",++cas,ans);}return 0;
}

这篇关于2019牛客暑期多校训练营(第七场)F Energy stones —— set+树状数组求随时间增长的区间和问题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/881188

相关文章

Java中的数组与集合基本用法详解

《Java中的数组与集合基本用法详解》本文介绍了Java数组和集合框架的基础知识,数组部分涵盖了一维、二维及多维数组的声明、初始化、访问与遍历方法,以及Arrays类的常用操作,对Java数组与集合相... 目录一、Java数组基础1.1 数组结构概述1.2 一维数组1.2.1 声明与初始化1.2.2 访问

go中的时间处理过程

《go中的时间处理过程》:本文主要介绍go中的时间处理过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1 获取当前时间2 获取当前时间戳3 获取当前时间的字符串格式4 相互转化4.1 时间戳转时间字符串 (int64 > string)4.2 时间字符串转时间

怎样通过分析GC日志来定位Java进程的内存问题

《怎样通过分析GC日志来定位Java进程的内存问题》:本文主要介绍怎样通过分析GC日志来定位Java进程的内存问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、GC 日志基础配置1. 启用详细 GC 日志2. 不同收集器的日志格式二、关键指标与分析维度1.

MySQL查询JSON数组字段包含特定字符串的方法

《MySQL查询JSON数组字段包含特定字符串的方法》在MySQL数据库中,当某个字段存储的是JSON数组,需要查询数组中包含特定字符串的记录时传统的LIKE语句无法直接使用,下面小编就为大家介绍两种... 目录问题背景解决方案对比1. 精确匹配方案(推荐)2. 模糊匹配方案参数化查询示例使用场景建议性能优

Java 线程安全与 volatile与单例模式问题及解决方案

《Java线程安全与volatile与单例模式问题及解决方案》文章主要讲解线程安全问题的五个成因(调度随机、变量修改、非原子操作、内存可见性、指令重排序)及解决方案,强调使用volatile关键字... 目录什么是线程安全线程安全问题的产生与解决方案线程的调度是随机的多个线程对同一个变量进行修改线程的修改操

关于集合与数组转换实现方法

《关于集合与数组转换实现方法》:本文主要介绍关于集合与数组转换实现方法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、Arrays.asList()1.1、方法作用1.2、内部实现1.3、修改元素的影响1.4、注意事项2、list.toArray()2.1、方

Redis出现中文乱码的问题及解决

《Redis出现中文乱码的问题及解决》:本文主要介绍Redis出现中文乱码的问题及解决,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1. 问题的产生2China编程. 问题的解决redihttp://www.chinasem.cns数据进制问题的解决中文乱码问题解决总结

Golang如何对cron进行二次封装实现指定时间执行定时任务

《Golang如何对cron进行二次封装实现指定时间执行定时任务》:本文主要介绍Golang如何对cron进行二次封装实现指定时间执行定时任务问题,具有很好的参考价值,希望对大家有所帮助,如有错误... 目录背景cron库下载代码示例【1】结构体定义【2】定时任务开启【3】使用示例【4】控制台输出总结背景

c++中的set容器介绍及操作大全

《c++中的set容器介绍及操作大全》:本文主要介绍c++中的set容器介绍及操作大全,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录​​一、核心特性​​️ ​​二、基本操作​​​​1. 初始化与赋值​​​​2. 增删查操作​​​​3. 遍历方

全面解析MySQL索引长度限制问题与解决方案

《全面解析MySQL索引长度限制问题与解决方案》MySQL对索引长度设限是为了保持高效的数据检索性能,这个限制不是MySQL的缺陷,而是数据库设计中的权衡结果,下面我们就来看看如何解决这一问题吧... 目录引言:为什么会有索引键长度问题?一、问题根源深度解析mysql索引长度限制原理实际场景示例二、五大解决