现在的位置: 首页 > 综合 > 正文

hdu 1698 Just a Hook(线段树基础)

2014年01月01日 ⁄ 综合 ⁄ 共 2062字 ⁄ 字号 评论关闭

成段更新的线段树,加入了延时标记............

线段树这种东西细节上的理解因人而异,还是要自己深入理解......慢慢来

#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <vector>
#include <set>
#include <queue>
#include <stack>
#include <climits>//形如INT_MAX一类的
#define MAX 100005
#define INF 0x7FFFFFFF
#define REP(i,s,t) for(int i=(s);i<=(t);++i)
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a))
#define mp(a,b) make_pair(a,b)
#define L(x) x<<1
#define R(x) x<<1|1
# define eps 1e-5
//#pragma comment(linker, "/STACK:36777216") ///传说中的外挂
using namespace std;
struct node {
    int left,right,mid,value,add;
} edge[4*MAX];

void push_up(int x) {
    edge[x].value = edge[x << 1].value + edge[x << 1 | 1].value ;
}

void build(int l,int r,int num) {
//l,r为当前节点的左右端点,num为当前节点在数组中的下标
    edge[num].left = l;
    edge[num].right = r;
    edge[num].mid = (l+r) >> 1;
    edge[num].add = 0;
    if(l == r) {
        edge[num].value = 1;
        return ;
    }
    if(l != r) { // 如果不是叶子节点
        build(l,edge[num].mid,num * 2); //左子树
        build(edge[num].mid + 1,r,num*2+1); //右子树
    }
    push_up(num);

}

void push_down(int x) {
    if(edge[x].add) {
        edge[x << 1].value = (edge[x << 1].right - edge[x << 1].left + 1 ) * edge[x].add ;
        edge[x << 1 | 1].value = (edge[x << 1 | 1].right - edge[x << 1 | 1].left + 1) * edge[x].add ;
        edge[x << 1].add = edge[x].add ;
        edge[x << 1 | 1].add = edge[x].add ;
        edge[x].add = 0 ;
    }
}
void update(int l, int r, int k, int num) {
    if(edge[num].left >= l && edge[num].right <= r) {
        //当前区间包含于更新区间
        edge[num].add = k;
        edge[num].value = (edge[num].right - edge[num].left + 1) * k;
        return;
    }
    push_down(num);
    if(edge[num].mid < l) update(l, r, k, num*2+1);
    else if(edge[num].mid >= r) update(l, r, k, num*2);
    else {
        update(l, edge[num].mid, k, num*2);
        update(edge[num].mid + 1, r, k, num*2+1);
    }
    push_up(num);
    
}

int query(int l,int r,int num) {
    if(l <= edge[num].left && r >= edge[num].right) {
        return edge[num].value;
    }
    //push_down(num);
    if(r <= edge[num].mid)
        return query(l,r,num*2);
    else if(l >= edge[num].mid + 1)
        return query(l,r,num *2+1);
    else {
        return query(l,edge[num].mid,num*2) + query(edge[num].mid+1,r,num*2+1);
    }
}

int main() {
    int t,n,i;
    cin >> t;
    int casee = 1;
    while(t--) {

        scanf("%d",&n);
        build(1,n,1);
        int m,a,b,c;
        scanf("%d",&m);
        while(m --) {
            scanf("%d%d%d",&a,&b,&c);
            update(a,b,c,1);
        }
        printf("Case %d: ",casee++);
        printf("The total value of the hook is %d.\n",query(1,n,1));
    }
    return 0;
}

抱歉!评论已关闭.