hdu 3954 Level up ยท line tree

Keywords: iOS

Title Solution

Meaning: a row of n level 1 heroes will upgrade their experience of fighting monsters. They will tell you the experience value required by each level. If you can't upgrade the experience value, you will be given two operations:

  1. W l r e for each wave of monsters, send heroes in the [l, R] range to fight, kill this wave of monsters, and each hero can obtain their own level * e points of experience
  2. The highest empirical value in the interval of Q l r query [l, r]

It's a very obvious line tree, but it's hard to update

After reading other people's codes, I'll make up the questions now,

Because every experience gained is related to the hero's own level, or the violent update doesn't need to be tried. I tried, TLE
Or add a lazy flag. When there is a hero in the interval to upgrade, update violently

Now, defining the lazy tag need [] means:
The ratio of the minimum required experience value to the hero level for the next upgrade within the range,

What is the ratio?
It's the monster e,
In this way, interval maintenance has nothing to do with hero level,

The general method is as follows:

  1. For each wave of monsters, add up e value and use all [] to maintain,
  2. For each wave of monsters, the maximum experience value in the range should be the original maximum experience value + the highest level in the range * the new e value (the continuous upgrade is also accumulated by the original level), and the maximum experience value in the range should be maintained by ekp []
  3. If the accumulated e value is enough to upgrade a hero in a certain interval, i.e. all ≥ \ ge ≥ e, the sub interval will be updated downward and the level of the hero will be updated. The experience has been updated in the second step. Moreover, because the update up is involved, the single point update is different from the interval update, so it needs to be distinguished

Oh, by the way, need [] should be rounded up

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
const int N = 1e5 + 10;
const int INF = 0x3f3f3f3f;
int n, m, k;

int Needk[N];
namespace seg_tree {//Line tree board

    int ekp[N * 4];//Maintain maximum experience value
    int all[N * 4];//Total monster e value
    int need[N * 4];//Required e-value (experience / level) 
    int rank[N * 4];//Maximum grade

    void pushdown(int l, int r, int rt);

    void levelup(int rt) {
        all[rt] = 0;
        while (ekp[rt] >= Needk[rank[rt] + 1]) rank[rt]++;
        int tmp = Needk[rank[rt] + 1] - ekp[rt];//Next level upgrade experience
        need[rt] = tmp / rank[rt] + (tmp % rank[rt] ? 1 : 0);
        //You can also use the ceil() function to round up
    }

    void pushup(int rt) {
        ekp[rt] = max(ekp[rt << 1], ekp[rt << 1 | 1]);
        rank[rt] = max(rank[rt << 1], rank[rt << 1 | 1]);
        need[rt] = min(need[rt << 1], need[rt << 1 | 1]);
    }

    void maintain(int l, int r, int rt, int e) {
        need[rt] -= e;
        all[rt] += e;
        ekp[rt] += rank[rt] * e;
        if (need[rt] <= 0) {
            if (l == r) levelup(rt);//Single point modification level
            else {
                pushdown(l, r, rt);//Interval modification
                pushup(rt);
            }
        }
    }

    void pushdown(int l, int r, int rt) {
        if (all[rt]) {
            int mid = l + r >> 1;
            maintain(l, mid, rt << 1, all[rt]);//Devolution monster
            maintain(mid + 1, r, rt << 1 | 1, all[rt]);
            all[rt] = 0;
        }
    }

    void build(int l, int r, int rt) {
        ekp[rt] = all[rt] = need[rt] = rank[rt] = 0;
        if (l == r) {
            rank[rt] = 1;
            need[rt] = Needk[2];
            return;
        }
        int mid = l + r >> 1;
        build(lson);
        build(rson);
        pushup(rt);
    }

    void update(int L, int R, int e, int l, int r, int rt) {
        if (L <= l && r <= R) {
            maintain(l, r, rt, e);
            return;
        }
        int mid = l + r >> 1;
        pushdown(l, r, rt);
        if (L <= mid) update(L, R, e, lson);
        if (R > mid) update(L, R, e, rson);
        pushup(rt);
    }

    int query(int L, int R, int l, int r, int rt) {
        if (L <= l && r <= R) {
            return ekp[rt];
        }
        int mid = l + r >> 1;
        pushdown(l, r, rt);
        int res = 0;
        if (L <= mid)res = max(res, query(L, R, lson));
        if (R > mid)res = max(res, query(L, R, rson));
        pushup(rt);
        return res;
    }
}
using namespace seg_tree;

string op;
int main() {
    ios::sync_with_stdio(0);

    int T;
    cin>>T;

    for (int cs = 1; cs <= T; ++cs) {
        printf("Case %d:\n", cs);

       	cin>>n>>k>>m;
        for (int i = 2; i <= k; ++i) {
            cin>>Needk[i];
        }
        Needk[k + 1] = INF;
        build(1, n, 1);

        for (int i = 1, l, r, e; i <= m; ++i) {
            cin>>op>>l>>r;
            if (op== "W") {
               	cin>>e;
                update(l, r, e, 1, n, 1);
            } else {
                printf("%d\n", query(l, r, 1, n, 1));
            }
        }
        puts("");//Format requirement
    }
    return 0;
}
Published 62 original articles, won praise 1, visited 2070
Private letter follow

Posted by jgetner on Fri, 21 Feb 2020 05:42:15 -0800