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

hdu – 1698 – Just a Hook(线段树(区间更新))

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

题意:一条DOTA链钩的长度为N,恰恰分成N节,每节价值为1,接着来Q次操作,X Y Z,把[X, Y]节上的价值设为Z,最后输出这条链钩的总价值。

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1698

——>>线段树区间修改。

#include <cstdio>
#include <algorithm>

using namespace std;

const int maxn = 100000 + 10;
int sumv[maxn<<2], setv[maxn<<2], X, Y, Z, _sum;

void maintain(int o, int L, int R)      //维护函数
{
    if(setv[o] >= 0) sumv[o] = setv[o]*(R-L+1);
    else if(L < R)sumv[o] = sumv[2*o] + sumv[2*o+1];        //L < R
}
void pushdown(int o)        //下传函数
{
    if(setv[o] >= 0)
    {
        setv[2*o] = setv[o];
        setv[2*o+1] = setv[o];
        setv[o] = -1;
    }
}
void update(int o, int L, int R)        //更新,将[X, Y]上的值设为Z
{
    if(X <= L && R <= Y) setv[o] = Z;
    else
    {
        pushdown(o);
        int M = L + (R - L) / 2;
        if(X <= M) update(2*o, L, M); else maintain(2*o, L, M);
        if(Y > M) update(2*o+1, M+1, R); else maintain(2*o+1, M+1, R);
    }
    maintain(o, L, R);
}
void query(int o, int L, int R)     //查询
{
    if(setv[o] >= 0) _sum += setv[o] * (min(R, Y)-max(L, X)+1);     //递归边界1:有set标记
    else if(X <= L && R <= Y) _sum += sumv[o];      //递归边界2:边界区间,此区间不被任何set操作影响
    else        //递归统计
    {
        int M = L + (R - L) / 2;
        if(X <= M) query(2*o, L, M);
        if(Y > M) query(2*o+1, M+1, R);
    }
}
void build(int o, int L, int R)     //建树
{
    if(L == R)
    {
        sumv[o] = 1;
        setv[o] = -1;
        return;
    }
    int M = L + (R - L) / 2;
    build(2*o, L, M);
    build(2*o+1, M+1, R);
    sumv[o] = R-L+1;        //初始为区间长度
    setv[o] = -1;       //-1表示没有被标记
}
int main()
{
    int T, N, Q, i, cnt = 1;
    scanf("%d", &T);
    while(T--)
    {
        scanf("%d%d", &N, &Q);
        build(1, 1, N);
        for(i = 1; i <= Q; i++)
        {
            scanf("%d%d%d", &X, &Y, &Z);
            update(1, 1, N);
        }
        _sum = 0;
        X = 1; Y = N;       //查询[X, Y]
        query(1, 1, N);
        printf("Case %d: The total value of the hook is %d.\n", cnt++, _sum);
    }
    return 0;
}

抱歉!评论已关闭.