设为首页 加入收藏

TOP

hdu 3954 Level up (线段树)
2014-11-23 19:19:01 来源: 作者: 【 】 浏览:5
Tags:hdu 3954 Level 线段

HH大神的神题。只能一直膜拜。。。

从线段树起步都是从他的博客里一点一滴的学的。

风格也是仿照他的来的。

然后说题目吧。

题目意思:会有很多波怪兽袭击,然后也有N个英雄。没来一波怪兽就派 编号是 L-R 的英雄去迎敌。

每个英雄都会获得一定的经验(既是 等级 * 每波的经验基数 E) 。最后Q操作就是问你 L-R 段中哪一个英雄的经验最高,并输出最高值。


开始的时候我有点混淆题目。如果他当时还获得的经验足够他升好几级的话,那么当他拿到经验之后,会马上升级,然后升一级以后自己的等级改变了。

把他获得的余下的经验再按新的等级来计算。那么就是雪球越滚越大。然后问了 最小公倍数 学长~~~嚯嚯


自己写的时候,是直接把LAZY (cov 数组) 往下推。然后自己意识到这样的lazy不能直接叠加 因为多次操作之后他的等级就会变。

之前的标记就没用了。 那我又想。那每来一个 cov 我就把之前的 cov往下推。 但是显然 这就如单点更新了。


通过上一段话,应该能明白代码中的 dis 变量作何用处了


dis 是指区间中 那个需求最少经验就可以的英雄 所需要的经验基数。 换句话说 如果这个人都还不能升级的话 那么这个区间内就不会有人能升级了。

那么就可以直接加上 cov 。

如果区间内那个人可以升级。以为这这段区间的某一个人的 lev会发生改变 此时我们就要把这个cov 一直往下推。找到那个变了的人。然后再更新区间。

#include 
#include 
#include 
#define lson num<<1,s,mid
#define rson num<<1|1,mid+1,e
#define maxn 10005
using namespace std;

int exp[maxn<<2],lev[maxn<<2];//区间最大经验   区间最大等级
int cov[maxn<<2],dis[maxn<<2];//lazy 标记数组  dis 如上
int ned[15]={0};
int K;

void pushup(int num)
{
    exp[num]=max(exp[num<<1],exp[num<<1|1]);
    lev[num]=max(lev[num<<1],lev[num<<1|1]);
    dis[num]=min(dis[num<<1],dis[num<<1|1]);
}
int getlev(int ex)//找到经验对应的等级
{
    if(ex>=ned[K-1])return K;
    for(int i=1;i<=K;i++)
    {
        if(ex>1;
    build(lson);
    build(rson);
}
void update(int num,int s,int e,int l,int r,int val)
{
    int mid=(s+e)>>1;
    if(s==e)
    {
        exp[num]+=lev[num]*val;
        lev[num]=getlev(exp[num]);
        dis[num]=(ned[lev[num]]-exp[num])/(lev[num])+((ned[lev[num]]-exp[num])%(lev[num])!=0);
        return ;
    }
    if(l<=s && r>=e)
    {
        if(valmid)update(rson,l,r,val);
    pushup(num);
}

int query(int num,int s,int e,int l,int r)
{
    if(s>=l && e<=r)
    {
        return exp[num];
    }
    pushdown(num);
    int mid=(s+e)>>1;
    if(r<=mid)return query(lson,l,r);
    else if(l>mid)return query(rson,l,r);
    else return max(query(lson,l,mid),query(rson,mid+1,r));
}
int main()
{
    int T,CASE=1;

    scanf("%d",&T);
    while(T--)
    {
        printf("Case %d:\n",CASE++);
        int n,qw;
        scanf("%d%d%d",&n,&K,&qw);

        for(int i=1;i 
 

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇HDU 4679 Terrorist’s destroy (.. 下一篇指向结构体变量的指针

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·求navicat for mysql (2025-12-26 13:21:33)
·有哪位大哥推荐一下m (2025-12-26 13:21:30)
·MySQL下载与安装教程 (2025-12-26 13:21:26)
·Linux_百度百科 (2025-12-26 12:51:52)
·Shell 流程控制 | 菜 (2025-12-26 12:51:49)