1. 程式人生 > >hdu1698 線段樹(區間更新~將區間[x,y]的值替換為z)

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.\n", ++kase, tre[1]);
    }
    return 0;
}