码迷,mamicode.com
首页 > 其他好文 > 详细

HDOJ 题目3954 Level up(线段树去见面更新区间查询)

时间:2015-08-30 16:01:00      阅读:215      评论:0      收藏:0      [点我收藏+]

标签:

Level up

Time Limit: 10000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3890    Accepted Submission(s): 1086


Problem Description
Level up is the task of all online games. It‘s very boooooooooring. There is only level up in those games, except level up.
In a online game, there are N heroes numbered id from 1 to N, each begins with level 1 and 0 Experience. They need to kill monsters to get Exp and level up.
技术分享

There are many waves of monsters, each wave, the heroes with id from li to ri will come to kill monsters and those hero with level k will get ei*k Exp. If one hero‘s Exp reach Needk then the hero level up to level k immediately.
After some waves, I will query the maximum Exp from li to ri.
Now giving the information of each wave and Needk, please tell me the answer of my query.
 

Input
The first line is a number T(1<=T<=30), represents the number of case. The next T blocks follow each indicates a case.
The first line of each case contains three integers N(1<=N<=10000), K(2<=K<=10) and QW(1<=QW<=10000)each represent hero number, the MAX level and querys/waves number.
Then a line with K -1 integers, Need2, Need3...Needk.(1 <= Need2 < Need3 < ... < Needk <= 10000).
Then QW lines follow, each line start with ‘W‘ contains three integers li ri ei (1<=li<=ri<=N , 1<=ei<=10000); each line start with ‘Q‘ contains two integers li ri (1<=li<=ri<=N).
 

Output
For each case, output the number of case in first line.(as shown in the sample output)
For each query, output the maximum Exp from li to ri.
Output a black line after each case.
 

Sample Input
2 3 3 5 1 2 W 1 1 1 W 1 2 1 Q 1 3 W 1 3 1 Q 1 3 5 5 8 2 10 15 16 W 5 5 9 W 3 4 5 W 1 1 2 W 2 3 2 Q 3 5 W 1 3 8 Q 1 2 Q 3 5
 

Sample Output
Case 1: 3 6 Case 2: 9 18 25
Hint
Case 1: At first ,the information of each hero is 0(1),0(1),0(1) [Exp(level)] After first wave, 1(2),0(1),0(1); After second wave, 3(3),1(2),0(1); After third wave, 6(3),3(3),1(2); Case 2: The information of each hero finally: 18(5) 18(5) 25(5) 5(2) 9(2)
 

Author
NotOnlySuccess
 

Source
 

Recommend
lcy   |   We have carefully selected several similar problems for you:  3340 3397 2871 1542 1828 

 很好的题,题目大意是有n个英雄,m个等级,q个操作,刚开始每个英雄都是等级1,经验0,下边m-1个整数,表示升每一级所需要的经验,下边跟q个操作,w a b c,区间【a,b】的英雄去打怪,获得的经验是英雄的等级*c,q a b,查询区间【a,b】中英雄最大的经验

ac代码

技术分享

#include<stdio.h>
#include<string.h>
#define INF 0x3f3f3f3f
#define max(a,b) (a>b?a:b)
#define min(a,b) (a>b?b:a)
struct s
{
	__int64 level,maxnum,flag,need;
	void init()
	{
		level=1;
		maxnum=0;
		flag=0;
	}
	void fun(__int64 val)
	{
		maxnum+=level*val;
		need-=val;
		flag+=val;
	}
}node[10005<<2];
__int64 need[15];
void pushdown(int tr)
{
	if(node[tr].flag)
	{
		node[tr<<1].fun(node[tr].flag);
		node[tr<<1|1].fun(node[tr].flag);
		node[tr].flag=0;
	}
}
void pushup(int tr)
{
	node[tr].maxnum=max(node[tr<<1].maxnum,node[tr<<1|1].maxnum);
	node[tr].level=max(node[tr<<1].level,node[tr<<1|1].level);
	node[tr].need=min(node[tr<<1].need,node[tr<<1|1].need);
}
void build(int l,int r,int tr)
{
	node[tr].init();
	node[tr].need=need[2];
	if(l==r)
		return;
	int mid=(l+r)>>1;
	build(l,mid,tr<<1);
	build(mid+1,r,tr<<1|1);
}
void update(int L,int R,int l,int r,int tr,int val)
{
	if(L<=l&&r<=R)
	{
		if(val>=node[tr].need)
		{
			if(l==r)
			{
				__int64 &now=node[tr].level;
				node[tr].maxnum+=now*val;
				while(node[tr].maxnum>=need[now+1])
					now++;
				__int64 temp=need[now+1]-node[tr].maxnum;
				node[tr].need=temp/now+(temp%now!=0);
			}
			else
			{
				pushdown(tr);
				int mid=(l+r)>>1;
				if(L<=mid)
					update(L,R,l,mid,tr<<1,val);
				if(R>mid)
					update(L,R,mid+1,r,tr<<1|1,val);
				pushup(tr);
			}
		}
		else
		{
			node[tr].fun(val);
		}
		return;
	}
		pushdown(tr);
		int mid=(l+r)>>1;
		if(L<=mid)
			update(L,R,l,mid,tr<<1,val);
		if(R>mid)
			update(L,R,mid+1,r,tr<<1|1,val);
		pushup(tr);
}
__int64 query(int L,int R,int l,int r,int tr)
{
	if(L<=l&&r<=R)
	{
		return node[tr].maxnum;
	}
	pushdown(tr);
	int mid=(l+r)>>1;
	__int64 temp1=0,temp2=0;
	if(L<=mid)
		temp1=query(L,R,l,mid,tr<<1);
	if(R>mid)
		temp2=query(L,R,mid+1,r,tr<<1|1);
	pushup(tr);
	return max(temp1,temp2);
}
int main()
{
	int t,c=0;
	scanf("%d",&t);
	while(t--)
	{
		int n,m,q,i,j;
		scanf("%d%d%d",&n,&m,&q);
		for(i=2;i<=m;i++)
			scanf("%I64d",&need[i]);
		need[m+1]=INF;
		build(1,n,1);
		printf("Case %d:\n",++c);
		while(q--)
		{
			char op[5];
			scanf("%s",op);
			if(op[0]=='W')
			{
				int a,b,c;
				scanf("%d%d%d",&a,&b,&c);
				update(a,b,1,n,1,c);
			}
			else
			{
				int a,b;
				scanf("%d%d",&a,&b);
				printf("%I64d\n",query(a,b,1,n,1));
			}
		}
		printf("\n");
	}
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

HDOJ 题目3954 Level up(线段树去见面更新区间查询)

标签:

原文地址:http://blog.csdn.net/yu_ch_sh/article/details/48104541

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!