hdu1698 线段树(区间更新~将区间[x,y]的值替换为z)

Just a Hook

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 45600    Accepted Submission(s): 21730


Problem 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.
 
题意:在DotA的游戏中,对于大多数英雄而言,Pudge的肉钩实际上是最可怕的。钩子由几根相同长度的连续金属棒组成。现在,帕吉希望在钩子上做一些操作。让我们将钩子的连续金属棒从1到N编号。对于每次操作,Pudge可以将连续的金属棒(从X到Y编号)改为铜棒,银棒或金棒。钩的总值计算为N个金属棒的值的总和。更准确地说,每种棒的价值计算如下:对于每个铜棒,值为1.对于每个银棒,值为2.对于每个金棒,值为3. Pudge想知道执行操作后钩子的总值。你可能会认为原来的钩子是由铜棒组成的。输入输入由几个测试用例组成。输入的第一行是案例的数量。不超过10个案例。对于每种情况,第一行包含整数N,1 <= N <= 100,000,这是Pudge肉钩的枝条数,第二行包含整数Q,0 <= Q <= 100,000,这是操作次数。接下来的Q行,每行包含三个整数X,Y,1 <= X <= Y <= N,Z,1 <= Z <= 3,它定义了一个操作:将从X到Y编号的枝条改为金属种类Z,其中Z = 1代表铜质种,Z = 2代表银种,Z = 3代表金种。输出对于每种情况,在一行中打印一个数字,表示操作后挂钩的总值。使用示例中的格式。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<cmath>
using namespace std;
const int maxn = 100000 + 10;
int t, n, x, y, z, q, tre[maxn * 4], laz[maxn * 4], kase = 0;
void push_up(int num)
{
    tre[num] = tre[num * 2] + tre[num * 2 + 1];
}
void pushdown(int num, int x, int y) 
{
    if (laz[num]) 
    {
        int mid = (x + y) / 2;
        laz[num * 2] = laz[num * 2 + 1] = laz[num];
        tre[num * 2] = (mid - x + 1) * laz[num];
        tre[num * 2 + 1] = (y - mid) * laz[num];
        laz[num] = 0;
    }
}
void build(int x, int y, int num) 
{
    int mid = (x + y) / 2;
    laz[num] = 0;
    if (x == y) 
    {
        tre[num] = 1; return;
    }
    build(x, mid, num * 1);
    build(mid + 1, y, num * 2 + 1);
    push_up(num);
}
void update(int le, int ri, int z, int x, int y, int num)
{
    int mid = (x + y) / 2;
    if (le <= x && y <= ri)
    {
        laz[num] = z;
        tre[num] = z * (y - x + 1);//先更新节点,但不继续往下更新,节点的值恰好是节点所在子树的和
        return;
    }
    pushdown(num, x, y);
    if (le <= mid)
        update(le, ri, z, x, mid, num * 2);
    if (mid < ri)
        update(le, ri, z, mid + 1, y, num * 2 + 1);
    push_up(num);
}
int query(int le, int ri, int x,int y,int num)
{
    if (le == ri)
    {
        return tre[num];
    }
    pushdown(num, x, y);
    int mid = (le + ri) / 2;
    if (x <= mid)
        return query(le, mid, x, y, num * 2);
    else
        return query(mid + 1, ri, x, y, num * 2 + 1);
}
int main() 
{
    scanf("%d", &t);
    while (t--)
    {
        scanf("%d%d", &n, &q);
        build(1, n, 1);
        while (q--) 
        {
            scanf("%d%d%d", &x, &y, &z);//将[x,y]的值更新为z
            update(x, y, z, 1, n, 1);
        }
        printf("Case %d: The total value of the hook is %d.
", ++kase, tre[1]);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/-citywall123/p/10046142.html