HDU 1698-Just a Hook

Description

In the game of DotA, Pudge’s meat hook is actually the most horrible thing for most of the heroes. The hook is made up of several consecutive metallic sticks which are of the same length.



Now Pudge wants to do some operations on the hook.

Let us number the consecutive metallic sticks of the hook from 1 to N. For each operation, Pudge can change the consecutive metallic sticks, numbered from X to Y, into cupreous sticks, silver sticks or golden sticks.
The total value of the hook is calculated as the sum of values of N metallic sticks. More precisely, the value for each kind of stick is calculated as follows:

For each cupreous stick, the value is 1.
For each silver stick, the value is 2.
For each golden stick, the value is 3.

Pudge wants to know the total value of the hook after performing the operations.
You may consider the original hook is made up of cupreous sticks.

Input

The input consists of several test cases. The first line of the input is the number of the cases. There are no more than 10 cases.
For each case, the first line contains an integer N, 1<=N<=100,000, which is the number of the sticks of Pudge’s meat hook and the second line contains an integer Q, 0<=Q<=100,000, which is the number of the operations.
Next Q lines, each line contains three integers X, Y, 1<=X<=Y<=N, Z, 1<=Z<=3, which defines an operation: change the sticks numbered from X to Y into the metal kind Z, where Z=1 represents the cupreous kind, Z=2 represents the silver kind and Z=3 represents the golden kind.

Output

For each case, print a number in a line representing the total value of the hook after the operations. Use the format in the example.

Sample Input

1
10
2
1 5 2
5 9 3

Sample Output

Case 1: The total value of the hook is 24.

题目分析

       这个hook是什么东西我也不知道,不过知道这个题需要改变某几个区间内的hook,然后最后输出所有的hook的值的总和。

       所以,典序的线段树区间更新,以此题为例,写一下线段树区间更新的代码模板。

       对于线段树的区间更新,我们为二叉树的每一个结点都多维护一个lazy,代表累加值,这个累加值是需要累加到当前结点的左右结点的,在这里,我们在访问某个区间之前(在这段代码里面是当前区间的左右区间),将当前区间的累加值分配到子区间去,这样可以保证我们在访问其子区间的时候保证累加值已经加到了这个区间代表的值里面。

代码区

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#include<sstream>
#include <iterator>
#include<cmath>
#include <map>
#define sf(a) scanf("%d",&a)
#define sff(a,b) scanf("%d%d",&a,&b)
#define sfff(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define sffff(a,b,c,d) scanf("%d%d%d%d",&a,&b,&c,&d)
#define slf(a) scanf("%lld",&a)
#define ssf(str) scanf("%s",str)
#define scf(ch) scanf("%c",&ch)
#define mem(s,data) memset(s,data,sizeof(s))
#define forL(i,a, b) for (int i = a; i <= b; i++)
#define forL(j,a, b) for (int j = a; j <= b; j++)
#define forR(i,a, b) for (int i = a; i >= b; i--)
#define forR(j,a, b) for (int j = a; j >= b; j--)
#define ltree(num) num<<1
#define rtree(num) num<<1|1
#define inf 0x3f3f3f3f
using namespace std;
const int max2 = 100 + 10;
const int max3 = 1000 + 10;
const int max4 = 10000 + 10;
const int max5 = 100000 + 10;
const int max6 = 1000000 + 10;
typedef long long ll;

typedef struct Tree{
    ll l;
    ll r;
    ll sum;
    ll lazy;
}Tree;

Tree tree[4 * max5];

void build(ll nl,ll nr,int num)
{
    tree[num].l = nl;
    tree[num].r = nr;
    tree[num].lazy = 0;
    if (nl == nr)
        //scanf("%lld", &tree[num].sum);
        tree[num].sum = 1;
    else
    {
        const ll mid = (nl + nr) >> 1;
        build(nl, mid, num << 1);
        build(mid + 1, nr, num << 1 | 1);
        tree[num].sum = tree[num << 1].sum + tree[num << 1 | 1].sum;
    }
}

void lazy_release(int num)
{
    if(tree[num].lazy)
    {
        const ll lazy = tree[num].lazy;
        tree[num << 1].lazy = lazy;
        tree[num << 1 | 1].lazy = lazy;

        tree[num << 1].sum = (tree[num << 1].r - tree[num << 1].l + 1)*lazy;
        tree[num << 1 | 1].sum = (tree[num << 1 | 1].r - tree[num << 1 | 1].l + 1)*lazy;
        tree[num].lazy = 0;
    }
}

void upData(ll fl,ll fr,ll value,int num)
{
    if (tree[num].l >= fl && tree[num].r <= fr)
    {
        tree[num].sum = (fr - fl + 1)*value;
        tree[num].lazy = value;
        return;
    }
    lazy_release(num);
    const ll mid = (tree[num].r + tree[num].l) >> 1;
    if (fr <= mid) upData(fl, fr, value, num << 1);                //查询区间和当前区间的左子树右重合
    else if (fl >  mid) upData(fl, fr, value, num << 1 | 1);
    else
    {
        upData(fl, mid, value, num << 1);
        upData(mid + 1, fr, value, num << 1|1);
    }
    tree[num].sum = tree[num << 1].sum + tree[num << 1 | 1].sum;    //更新当前区间
    //cout << "[ " << tree[num].l << "," << tree[num].r << "] = " << tree[num].sum << endl;
}


int main()
{
    int t;
    int kCase = 0;
    scanf("%d", &t);
    while(t--)
    {
        int n;
        scanf("%d", &n);
        build(1, n, 1);
        int m;
        scanf("%d", &m);
        //cout << "---" << tree[1].sum << "---" << endl;
        while(m--)
        {
            ll l, r, v;
            scanf("%lld%lld%lld", &l, &r, &v);
            upData(l, r, v, 1);
            //cout <<"---"<< tree[1].sum <<"---"<< endl;
        }
        printf("Case %d: The total value of the hook is %lld.
", ++kCase, tree[1].sum);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/winter-bamboo/p/10634452.html