Just a Hook HDU

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. 

InputThe 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. 
OutputFor 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.

题意:有一个多截棍,起初它是有同制造的,现在我想把指定区间内的棍都换成其他材质的,比如银的,或金的。一节铜双截棍是1元,一节银双截棍是2元,一节金双截棍是3元。问最后这个多截棍值多少钱。
输入第一行表示样例数(小于10),然后每个样例的第一行为多截棍的节数(1~100000),第二行为改变的次数q(1~100000),然后q行,每行三个数a,b,c:表示将a到b的棍换成价值为c元棍。
输入格式按照样例。

思路:这是一个简单的线段树题,它只用到了区间修改的方法,我就不多说了。

代码:
  1 #include <cstdio>
  2 #include <fstream>
  3 #include <algorithm>
  4 #include <cmath>
  5 #include <deque>
  6 #include <vector>
  7 #include <queue>
  8 #include <string>
  9 #include <cstring>
 10 #include <map>
 11 #include <stack>
 12 #include <set>
 13 #include <sstream>
 14 #include <iostream>
 15 #define mod 998244353
 16 #define eps 1e-6
 17 #define ll long long
 18 #define INF 0x3f3f3f3f
 19 using namespace std;
 20 
 21 struct node
 22 {
 23     //l表示左边,r表示右边,sum表示该线段的值
 24     int l,r,sum;
 25     //lazy为标记,为方便区间修改
 26     int lazy;
 27 };
 28 node no[100000*8];
 29 
 30 //初始化
 31 //k表示当前节点的编号,l表示当前区间的左边界,r表示当前区间的右边界
 32 void build(int k,int l,int r)
 33 {
 34     no[k].l=l;
 35     no[k].r=r;
 36     //如果递归到最低点
 37     if(l==r)
 38     {
 39         no[k].sum=1;
 40         return ;
 41     }
 42     //对半分
 43     int mid=(l+r)/2;
 44     //递归到左线段
 45     build(k*2,l,mid);
 46     //递归到右线段
 47     build(k*2+1,mid+1,r);
 48     //更新当前节点的值
 49     no[k].sum=no[k*2].sum+no[k*2+1].sum;
 50 }
 51 
 52 //传递标记
 53 void pushdown(int k)
 54 {
 55     //当前节点不是最低层时
 56     if(no[k].l!=no[k].r)
 57     {
 58         //更新子节点的值
 59         no[k*2].sum=(no[k*2].r-no[k*2].l+1)*no[k].lazy;
 60         no[k*2+1].sum=(no[k*2+1].r-no[k*2+1].l+1)*no[k].lazy;
 61         //更新子节点的标记
 62         no[k*2].lazy=no[k*2+1].lazy=no[k].lazy;
 63     }
 64     //清除当前节点的标记
 65     no[k].lazy=0;
 66 }
 67 
 68 //区间修改
 69 void change(int k,int l,int r,int x)
 70 {
 71     //检查并下传标记
 72     if(no[k].lazy)
 73     {
 74         pushdown(k);
 75     }
 76     //到对应层时更新值与标记
 77     if(no[k].l==l&&no[k].r==r)
 78     {
 79         no[k].sum=(no[k].r-no[k].l+1)*x;
 80         no[k].lazy=x;
 81         return ;
 82     }
 83     //取中值
 84     int mid=(no[k].l+no[k].r)/2;
 85     
 86     if(r<=mid)
 87     {
 88         //如果被修改区间完全在左区间
 89         change(k*2,l,r,x);
 90     }
 91     else if(l>mid)
 92     {
 93         //如果被修改区间完全在右区间
 94         change(k*2+1,l,r,x);
 95     }
 96     else
 97     {
 98         //如果都不在,就要把修改区间分解成两块,分别往左右区间递归
 99         change(k*2,l,mid,x);
100         change(k*2+1,mid+1,r,x);
101     }
102     //更新当前节点的值
103     no[k].sum=no[k*2].sum+no[k*2+1].sum;
104 }
105 
106 int main()
107 {
108     int m,n;
109     int ans=1;
110     scanf("%d",&m);
111     while(m--)
112     {
113         //对每个测试样例都要初始化
114         memset(no,0,sizeof(no));
115         scanf("%d",&n);
116         //构建线段树
117         build(1,1,n);
118         int q;
119         scanf("%d",&q);
120         int a,b,c;
121         for(int i=0;i<q;i++)
122         {
123             scanf("%d %d %d",&a,&b,&c);
124             //执行修改操作
125             change(1,a,b,c);
126         }
127         printf("Case %d: The total value of the hook is %d.
",ans++,no[1].sum);
128     }
129 }
原文地址:https://www.cnblogs.com/mzchuan/p/11787475.html