HUT-XXXX Money out of Thin Air 線段樹

來源:互聯網
上載者:User

該題題義是給定一個公司的結構,然後針對每個員工的一系列操作。由於問題牽涉到一個員工以及一個員工所領導的部門,因此用普通線性結構顯然效率太低。這裡用到了線段樹。

step1:首先我們要確定題目是要對給定的點或者是區間進行操作,那麼我們自然而然會想到線段樹,但是這題還不是直接的線段樹,需要對題中給定的關係進行離散話,也就是按
    照先序或者是後序遍曆進行排序,這樣某一個員工所領導的部門下的成員就在物理上連續了,並且我們用兩個數組分別記錄某個成員所領導的部門的左邊界和右邊界。

step2:有了上一步的操作後,我們就可以進行構樹了,按照普通的線段樹進行構建,線段樹僅僅只是我們處理點和區間的一種資料結構,其本身沒有什麼實際意義,記得用一個映
    射將線段樹的點和實際員工的編號聯絡起來,這樣方便了初始化,也便於最後的輸出。

step3:此時我們就可以來處理資料中所給定的操作了,點更新和區間更新,當然這裡可以用到lazy標記。

PS:由於整個數很可能退化成鏈表,所以最好使用非遞迴來實現先序或者是後序遍曆。

代碼如下:

#include <cstring>#include <cstdio>#include <cstdlib>#include <algorithm>#include <queue>#define MAXN 50005using namespace std;int N, Q, s[MAXN], stk[MAXN], visit[MAXN], top;int seq[MAXN], idx, L[MAXN], R[MAXN];typedef long long int Int64;queue<int>q[50005];struct Node{    int l, r;    Int64 sum, lazy;}e[200005];void getseq(int boss) {      int pos;    idx = -1;    top = 1;    stk[top] = boss;    memset(visit, 0, sizeof (visit));    while (top) {        pos = stk[top];        if (!visit[pos]) {            visit[pos] = 1;            seq[++idx] = pos;             L[pos] = idx;         }        if (!q[pos].empty()) {             stk[++top] = q[pos].front();            q[pos].pop();        }        else {            R[pos] = idx;             --top;        }    }}void build(int p, int l, int r){     e[p].l = l, e[p].r = r;    e[p].lazy = 0;    if (l!= r) {        int mid = (l + r) >> 1;        build(p<<1, l, mid);        build(p<<1|1, mid+1, r);        e[p].sum = e[p<<1].sum + e[p<<1|1].sum;    }    else {  // l == r         e[p].sum = s[seq[l]];     }}inline void update(int p){    e[p].sum = e[p<<1].sum + e[p<<1|1].sum;}Int64 sum(int p, int l, int r){    if (e[p].l == l && r == e[p].r) {        return e[p].sum;    }    int mid = (e[p].l + e[p].r) >> 1;    if (e[p].lazy) {        e[p<<1].lazy += e[p].lazy;        e[p<<1|1].lazy += e[p].lazy;        e[p<<1].sum += (e[p<<1].r-e[p<<1].l+1)*e[p].lazy;        e[p<<1|1].sum += (e[p<<1|1].r-e[p<<1|1].l+1)*e[p].lazy;        e[p].lazy = 0;    }    if (r <= mid) {        return sum(p<<1, l, r);    }    else if (l > mid) {        return sum(p<<1|1, l, r);    }    else {        return sum(p<<1, l, mid) + sum(p<<1|1, mid+1, r);    }}void modify(int p, int l, int r, Int64 x){    if (e[p].l == l && r == e[p].r) {        e[p].lazy += x;        e[p].sum += (e[p].r-e[p].l+1) * x;        // 身上有延時標記,但是本身的值一定要是正確的        return;    }    int mid = (e[p].l + e[p].r) >> 1;    if (e[p].lazy) {        e[p<<1].lazy += e[p].lazy;        e[p<<1|1].lazy += e[p].lazy;        e[p<<1].sum += (e[p<<1].r-e[p<<1].l+1)*e[p].lazy;        e[p<<1|1].sum += (e[p<<1|1].r-e[p<<1|1].l+1)*e[p].lazy;        e[p].lazy = 0;    }    if (r <= mid) {        modify(p<<1, l, r, x);    }    else if (l > mid) {        modify(p<<1|1, l, r, x);    }    else {        modify(p<<1, l, mid, x);        modify(p<<1|1, mid+1, r, x);    }    update(p);}int main(){     int p, x, y, z, first = 1;    Int64 level;    char op[15];    while (scanf("%d %d %d", &N, &Q, &s[0]), N|Q|s[0]) {        if (first) {            first = 0;        }        else {            puts("");        }        for (int i = 1; i < N; ++i) {            scanf("%d %d", &p, &s[i]);            q[p].push(i);         }         getseq(0);        build(1, 0, N-1);  // 區間劃分是 0 - N-1        while (Q--) {            scanf("%s %d %d %d", op, &x, &y, &z);            if (op[0] == 'e') {                level = sum(1, L[x], L[x]);                if (level < y) {                    modify(1, L[x], L[x], z);                }            }            else {                level = sum(1, L[x], R[x]);                if (1.*level/((R[x]-L[x]+1)) < y) {                    modify(1, L[x], R[x], z);                }            }        }        for (int i = 0; i < N; ++i) {            printf("%lld\n", sum(1, L[i], L[i]));        }    }    return 0;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.