转载请注明出处,谢谢 http://blog.csdn.net/ACM_cxlove?viewmode=contents           by---cxlove

HDU 3954 level up

http://acm.hdu.edu.cn/showproblem.php?pid=3954

HH的神题,想当初阿里巴巴这比赛是第一次参加的网上的比赛,还是组队的。结果被HH的一套神题完虐

一直都很崇拜HH大牛,

1、第一位开启“网吧通宵刷题模式”的队员(注:当时大一不允许带电脑,在一片充满游戏、电影以及美女图片的屏幕中能看到有人敲代码,你不觉得很酷吗?),此热情深深影响一届人;
2、第一位在第一学期就担任集训队副队长的队员;
3、第一位在大一就获得省赛金牌的队员(大学之前0基础);
4、第一位本科期间入围百度之星总决赛的队员(2010、2011年2次入围百度之星总决赛);
5、第一位大二就参加World Final的队员;
6、第一位2度参加World Final的队员(大二、大三参加World Final,无奈大四只能退役);
7、第一位带领队伍省赛捧杯的队员(2011年浙江省第8届省赛);
8、第一位大学4年3夺省赛金牌的队员;
……

不仅仅因为HH取得的成绩,他的精神感染了我,从零基础成为一名在ACM界赫赫有名的大牛。

言归正传,回到题目,区间更新,获得一定的经验可以升级,而每次获得的经验是和等级有关的,这是个难点。

区间lazy是必然的,否则必然TLE。而每次的lazy和以前不一样,由于之后的经验和等级有关,之前lazy的部分可能会导致升级,那之后的就不能按原来的lazy了。

只需要计算区间里的最大等级,经验,以及距离升级需要最小的经验基数(而不是经验总量,每次获得的经验是基数乘以等级的)。

/*
ID:cxlove
PROB:hdu 3954
DATA:2012.5.8
HINT:线段树
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<map>
#include<algorithm>
#define LL long long
using namespace std;
int sum[15],n,k,q;
struct Line{
int left,right,mid;
int exp,level;   //区间最大的经验,等级
int min_dist,lazy;   //区间升级所需的最少经验基数,懒惰标记
}L[50005];
//建树
void bulid(int step,int l,int r){
L[step].left=l;
L[step].right=r;
L[step].mid=(l+r)/2;
L[step].min_dist=sum[1];    //初始等级为1,所以经验基数便是sum[1]/1
L[step].exp=0;         //初始经验为0
L[step].level=1;         //初始等级为1
L[step].lazy=0;
if(l==r)
return;
bulid(2*step,l,(l+r)/2);
bulid(2*step+1,(l+r)/2+1,r);
}
//向下更新,lazy更新到子节点
void PushDown(int step){
L[2*step].exp+=L[step].lazy*L[2*step].level;
L[2*step].min_dist-=L[step].lazy;
L[2*step].lazy+=L[step].lazy;
L[2*step+1].exp+=L[step].lazy*L[2*step+1].level;
L[2*step+1].min_dist-=L[step].lazy;
L[2*step+1].lazy+=L[step].lazy;
L[step].lazy=0;
}
//向上更新,更新了子节点后,更新父节点
void PushUp(int step){
L[step].exp=max(L[2*step].exp,L[2*step+1].exp);
L[step].level=max(L[2*step].level,L[2*step+1].level);
L[step].min_dist=min(L[2*step].min_dist,L[2*step+1].min_dist);
}
//更新操作
void update(int step,int l,int r,int e){
//叶子节点
if(L[step].left==L[step].right){
L[step].exp+=L[step].level*e;
while(L[step].exp>=sum[L[step].level])
L[step].level++;
//计算还需要多少经验基数升级
L[step].min_dist=(sum[L[step].level]-L[step].exp)/L[step].level+((sum[L[step].level]-L[step].exp)%L[step].level!=0);
return ;
}
if(L[step].left==l&&L[step].right==r){
//区间内有英雄要升级了
if(e>=L[step].min_dist){
//lazy更新子节点
PushDown(step);
//更新子区间
update(2*step,l,(l+r)/2,e);
update(2*step+1,(l+r)/2+1,r,e);
//更新父节点
PushUp(step);
}
//当前没有英雄升级
else{
L[step].exp+=L[step].level*e;
L[step].min_dist-=e;
L[step].lazy+=e;
}
return ;
}
//向下更新
if(L[step].lazy)
PushDown(step);
if(r<=L[step].mid)
update(2*step,l,r,e);
else if(l>L[step].mid)
update(2*step+1,l,r,e);
else{
update(2*step,l,L[step].mid,e);
update(2*step+1,L[step].mid+1,r,e);
}
PushUp(step);
}
int query(int step,int l,int r){
if(L[step].left==l&&L[step].right==r)
return L[step].exp;
if(L[step].lazy)
PushDown(step);
if(r<=L[step].mid)
return query(2*step,l,r);
else if(l>L[step].mid)
return query(2*step+1,l,r);
else
return max(query(2*step,l,L[step].mid),query(2*step+1,L[step].mid+1,r));
}
int main(){
int t,cas=0;
scanf("%d",&t);
while(t--){
scanf("%d%d%d",&n,&k,&q);
for(int i=1;i<k;i++)
scanf("%d",&sum[i]);
sum[k]=1<<30;   //这里不可少
printf("Case %d:\n",++cas);
bulid(1,1,n);
while(q--){
char str[10];
int x,y,e;
scanf("%s",str);
if(str[0]=='W'){
scanf("%d%d%d",&x,&y,&e);
update(1,x,y,e);
}
else{
scanf("%d%d",&x,&y);
printf("%d\n",query(1,x,y));
}
}
printf("\n");
}
return 0;
}

HDU 3954 level up 线段树相关推荐

  1. HDU 3954 Level up(线段树)

    HDU 3954 Level up 题目链接 题意:k个等级,n个英雄,每一个等级升级有一定经验,每次两种操作,一个区间加上val,这样区间内英雄都获得当前等级*val的经验,还有一个操作询问区间经验 ...

  2. hdu 3397 Sequence operation(线段树,lazy,区间合并)

    hdu 3397 Sequence operation 线段树lazy和区间合并结合的一个题,相当于几个题集中到一起嘛,分开想就好了 0,1,2操作都要lazy,2的异或操作找到每一只含1或只含0的区 ...

  3. 2016 Multi-University Training Contest 10 [HDU 5861] Road (线段树:区间覆盖+单点最大小)...

    HDU 5861 题意 在n个村庄之间存在n-1段路,令某段路开放一天需要交纳wi的费用,但是每段路只能开放一次,一旦关闭将不再开放.现在给你接下来m天内的计划,在第i天,需要对村庄ai到村庄bi的道 ...

  4. hdu 2871 Memory Control(线段树)

    题目链接:hdu 2871 Memory Control 题目大意:模拟一个内存分配机制. Reset:重置,释放全部空间 New x:申请内存为x的空间,输出左地址 Free x:释放地址x所在的内 ...

  5. HDU 4031 Attack(线段树/树状数组区间更新单点查询+暴力)

    Attack Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others) Total Sub ...

  6. HDU 4262 Juggler (模拟+线段树优化)

    转载请注明出处,谢谢http://blog.csdn.net/acm_cxlove/article/details/7854526       by---cxlove http://acm.hdu.e ...

  7. HDU 5669 Road(线段树建树)(分层图最短路)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5669 [分析]线段树建树+分层图最短路 #include <cstdio> #includ ...

  8. HDU - I Hate It(线段树)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1754 Time Limit: 9000/3000 MS (Java/Others) Memory Li ...

  9. HDU - 3333 Turing Tree 线段树区间不同值和+详解+思想

    传送门 首先第一次做这种求不同元素和的线段树题,猜想是个裸题.但是题目中有一句话显然给题目降低了很大的难度,就是 想想其实它就是在暗示你这道题你要结合多次询问来处理,也就是所谓的离线,而不是一次一次的 ...

  10. HDU 3333-Turing Tree(线段树解决离线询问)

    题意: 给定一个长度为n的序列,给定m个查询,每次查询区间[L,R]范围内不同元素的和. 题解: x,yx,yx,y为查询的区间左右端点 用一个数组left[i]left[i]left[i],表示左边 ...

最新文章

  1. ProGen:蛋白质生成语言模型
  2. SAP HUMO VLMOVE不支持E库存发货到成本中心
  3. JavaScript之充实文档的内容
  4. python代码壁纸-Python爬取高清壁纸
  5. 算法提高课-搜索-Flood fill算法-AcWing 1098. 城堡问题:flood fill、bfs
  6. 多线程设计模式(四):生产者-消费模式
  7. 公共mysql数据库_公共MySQL的数据库服务器层
  8. 教师节我用Python分析了336个赞美老师的句子,满满的幸福和开心
  9. webuploader项目中多图片上传实例
  10. 四 国内IP核相关企业及其分析
  11. 计算机本地硬盘满了,本地磁盘C盘满了怎么清理?
  12. AutoCAD.NET开发:PaletteSet
  13. 美团点评2020年秋季校园招聘启动啦
  14. Second season seventh episode,Ross finds out Rachel like him,what will he do???
  15. uniapp app内使用微信H5支付
  16. SAP中库存确定组的应用简析
  17. 北京软件开发商城app系统软件开发大概多少钱
  18. JSONObject简介 - 月月鸟0820 - 博客园
  19. 直播频频翻车:追风口的人,变成风口杀手
  20. python中import random_[零基础学python]Import 模块

热门文章

  1. javaweb学习(5)--Cookie
  2. Linux中的基础I/O
  3. 人工智能初步学习笔记
  4. 农夫山泉病毒性营销方案策划
  5. centos7搭建webpack
  6. 【org.mybatis.spring.MyBatisSystemException】There is no getter for property named ‘array‘‘
  7. 苹果电脑可以装windows系统吗_苹果电脑MacBook双系统安装好后,如何下载Windows支持组件?...
  8. MongoDB 认证、添加用户、用户权限控制
  9. kettle Call From LAPTOP-14BPR3NI/192.168.1.2 to locahost:8020 failed on connection
  10. SDCC 2016讲师、知名JavaScript专家周爱民议题公布:有前端思想的物联网系统架构...