HDU 4970 Killing Monsters 线段树 || 树状数组

本文探讨了C++模板元编程技术在实现段树数据结构中的应用,包括节点定义、初始化、更新和查询操作,展示了如何利用元编程简化代码并提高效率。

。。卡常数T^T,

#include <cstdio>
#include <cstring>

const int MAX_N = 100007;

#define lson idx<<1
#define rson idx<<1|1

struct Node {
    int l, r;
    long long add, sum;
};

int n, m, k;
long long f[MAX_N];
long long all[MAX_N];
Node tree[MAX_N << 3];

struct Segment {
    void up(int idx) {
        tree[idx].sum = tree[lson].sum + tree[rson].sum;
    }
    void down(int idx) {
        if (tree[idx].add > 0) {
            tree[lson].add += tree[idx].add;
            tree[rson].add += tree[idx].add;
            tree[lson].sum += tree[idx].add * (tree[lson].r - tree[lson].l + 1);
            tree[rson].sum += tree[idx].add * (tree[rson].r - tree[rson].l + 1);
            tree[idx].add = 0;
        }
    }
    void build(int idx, long long L, long long R) {
        tree[idx].l = L, tree[idx].r = R;
        tree[idx].add = tree[idx].sum = 0;
        if (L == R) return ;
        int mid = (L + R) >> 1;
        build(lson, L, mid);
        build(rson, mid+1, R);
    }
    void update_add(long long y1, long long y2, int idx, long long val) {
        if (tree[idx].l == y1 && tree[idx].r == y2) {
            tree[idx].add += val;
            tree[idx].sum += val * (tree[idx].r - tree[idx].l + 1);
            return ;
        }
        down(idx);
        int mid = (tree[idx].l + tree[idx].r) >> 1;
        if (y2 <= mid) update_add(y1, y2, lson, val);
        else if (y1 > mid) update_add(y1, y2, rson, val);
        else {
            update_add(y1, mid, lson, val);
            update_add(mid+1, y2, rson, val);
        }
        up(idx);
    }
    long long query_sum(long long y1, long long y2, int idx) {
        if (tree[idx].l == y1 && tree[idx].r == y2) {
            return tree[idx].sum;
        }
        down(idx);
        int mid = (tree[idx].l + tree[idx].r) >> 1;
        if (y2 <= mid) return query_sum(y1, y2, lson);
        else if (y1 > mid) return query_sum(y1, y2, rson);
        else return query_sum(y1, mid, lson) + query_sum(mid+1, y2, rson);
    }
};

inline bool rd(long long &n){  
    long long x = 0, tmp = 1;  
    char c = getchar();  
    while((c < '0' || c > '9') && c != '-' && c != EOF) c = getchar();  
    if(c == EOF) return false;  
    if(c == '-') c = getchar(), tmp = -1;  
    while(c >= '0' && c <= '9') x *= 10, x += (c - '0'),c = getchar();  
    n = x*tmp;  
    return true;
}  

int main() {
   while (1 == scanf("%d", &n)) {
       if (0 == n) break;
       scanf("%d", &m);
    Segment seg;
       seg.build(1, 1, n);
       for (int i = 0; i < m; ++i) {
           long long l, r, val;
           rd(l), rd(r), rd(val);
           seg.update_add(l, r, 1LL, val);
       }
       scanf("%d", &k);
       for (int i = 1; i <= n; ++i) {
           f[i] = seg.query_sum(i, i, 1LL);
       }
       all[0] = 0;
       for (int i = 1; i <= n; ++i) {
           all[i] = all[i - 1] + f[i];
       }
       int cnt = 0;
       for (int i = 0; i < k; ++i) {
           long long hi, xi;
           rd(hi), rd(xi);
           long long d = all[n] - all[xi - 1];
           if (d >= hi) ++cnt;
       }
       int ans = k - cnt;
       printf("%d\n", ans);
   }
    return 0;
}


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值