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

相关文章

mybatis和mybatis-plus设置值为null不起作用问题及解决

《mybatis和mybatis-plus设置值为null不起作用问题及解决》Mybatis-Plus的FieldStrategy主要用于控制新增、更新和查询时对空值的处理策略,通过配置不同的策略类型... 目录MyBATis-plusFieldStrategy作用FieldStrategy类型每种策略的作

C++初始化数组的几种常见方法(简单易懂)

《C++初始化数组的几种常见方法(简单易懂)》本文介绍了C++中数组的初始化方法,包括一维数组和二维数组的初始化,以及用new动态初始化数组,在C++11及以上版本中,还提供了使用std::array... 目录1、初始化一维数组1.1、使用列表初始化(推荐方式)1.2、初始化部分列表1.3、使用std::

C++ Primer 多维数组的使用

《C++Primer多维数组的使用》本文主要介绍了多维数组在C++语言中的定义、初始化、下标引用以及使用范围for语句处理多维数组的方法,具有一定的参考价值,感兴趣的可以了解一下... 目录多维数组多维数组的初始化多维数组的下标引用使用范围for语句处理多维数组指针和多维数组多维数组严格来说,C++语言没

linux下多个硬盘划分到同一挂载点问题

《linux下多个硬盘划分到同一挂载点问题》在Linux系统中,将多个硬盘划分到同一挂载点需要通过逻辑卷管理(LVM)来实现,首先,需要将物理存储设备(如硬盘分区)创建为物理卷,然后,将这些物理卷组成... 目录linux下多个硬盘划分到同一挂载点需要明确的几个概念硬盘插上默认的是非lvm总结Linux下多

Python Jupyter Notebook导包报错问题及解决

《PythonJupyterNotebook导包报错问题及解决》在conda环境中安装包后,JupyterNotebook导入时出现ImportError,可能是由于包版本不对应或版本太高,解决方... 目录问题解决方法重新安装Jupyter NoteBook 更改Kernel总结问题在conda上安装了

pip install jupyterlab失败的原因问题及探索

《pipinstalljupyterlab失败的原因问题及探索》在学习Yolo模型时,尝试安装JupyterLab但遇到错误,错误提示缺少Rust和Cargo编译环境,因为pywinpty包需要它... 目录背景问题解决方案总结背景最近在学习Yolo模型,然后其中要下载jupyter(有点LSVmu像一个

解决jupyterLab打开后出现Config option `template_path`not recognized by `ExporterCollapsibleHeadings`问题

《解决jupyterLab打开后出现Configoption`template_path`notrecognizedby`ExporterCollapsibleHeadings`问题》在Ju... 目录jupyterLab打开后出现“templandroidate_path”相关问题这是 tensorflo

如何解决Pycharm编辑内容时有光标的问题

《如何解决Pycharm编辑内容时有光标的问题》文章介绍了如何在PyCharm中配置VimEmulator插件,包括检查插件是否已安装、下载插件以及安装IdeaVim插件的步骤... 目录Pycharm编辑内容时有光标1.如果Vim Emulator前面有对勾2.www.chinasem.cn如果tools工

如何利用Java获取当天的开始和结束时间

《如何利用Java获取当天的开始和结束时间》:本文主要介绍如何使用Java8的LocalDate和LocalDateTime类获取指定日期的开始和结束时间,展示了如何通过这些类进行日期和时间的处... 目录前言1. Java日期时间API概述2. 获取当天的开始和结束时间代码解析运行结果3. 总结前言在J

最长公共子序列问题的深度分析与Java实现方式

《最长公共子序列问题的深度分析与Java实现方式》本文详细介绍了最长公共子序列(LCS)问题,包括其概念、暴力解法、动态规划解法,并提供了Java代码实现,暴力解法虽然简单,但在大数据处理中效率较低,... 目录最长公共子序列问题概述问题理解与示例分析暴力解法思路与示例代码动态规划解法DP 表的构建与意义动