在 DotA 的游戏中,Pudge 的肉钩实际上是大多数英雄最可怕的东西。挂钩由几个长度相同的连续金属棒组成。现在 Pudge 想在钩子上做一些操作。
让我们将钩子的连续金属棒从 1 到 N 编号。对于每次操作,Pudge 可以将编号从 X 到 Y的连续金属杆更改为铜棒、银棒或金棒。
钩子的总值计算为 N 根金属棒的值之和。更准确地说,每种棍子的值计算如下:
对于每个铜棒,其值为 1。
对于每个银棒,其值为 2。
对于每根金棒,其值为 3。
Pudge想知道执行操作后钩子的总值。你会认为原来的钩子是由铜棒制成的。
输入由几个测试用例组成。输入的第一行是案例的数量。样例不超过 10 例。
对于每种情况,第一行包含整数 N ( 1 ≤ N ≤ 100000 ) N(1 \leq N \leq 100000) N(1≤N≤100000),这是 Pudge 肉钩的棒数,第二行包含整数 Q ( 0 ≤ Q ≤ 10000 ) Q(0 \leq Q \leq 10000) Q(0≤Q≤10000),这是操作数。
接下来的 Q 行,每行包含三个整数 X 、 Y ( 1 ≤ X ≤ Y ≤ N ) , Z ( 1 ≤ Z ≤ 3 ) X、Y(1 \leq X \leq Y \leq N),Z(1 \leq Z \leq 3) X、Y(1≤X≤Y≤N),Z(1≤Z≤3)。
定义了一个操作:将从 X 到 Y 编号的棒更改为金属类 Z,其中 Z=1 表示铜类,Z=2 表示银类,Z=3 表示金类。
对于每种情况,在一行中打印一个数字,表示操作后钩子的总值。
1
10
2
1 5 2
5 9 3
Case 1: The total value of the hook is 24.
https://acm.hdu.edu.cn/showproblem.php?pid=1698
样例解释:
一组样例,10 根金属棒,两次操作。初始的时候每一个数为 1。
1 5 2
,把区间 [1,5] 每个数改为 2,更改后区间为: 2 2 2 2 2 1 1 1 1 1
5 9 3
,把区间 [5,9] 每个数改为 3,更改后区间为:2 2 2 2 3 3 3 3 3 1
结束后整根棒子的总和为 24
建树,区间更新,标记下传
#include
#include
#include
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 9;
ll sum[maxn << 2] , add[maxn << 2];
int n , q , t;
void build(int l , int r , int k)
{
if(l == r)
{
sum[k] = 1;
return;
}
int mid = (l + r) >> 1;
build(l , mid , k << 1);
build(mid + 1 , r , k << 1 | 1);
sum[k] = sum[k << 1] + sum[k << 1 | 1];
}
void Add(int value , int l , int r ,int k)
{
add[k] = value;
sum[k] = value * (r - l + 1);
}
void pushdown(int value , int l , int mid , int r , int k)
{
if(add[k] == 0)
return;
Add(add[k] , l , mid , k << 1);
Add(add[k] , mid + 1 , r , k << 1 | 1);
add[k] = 0;
}
void update(int x , int y ,int value , int l , int r , int k)
{
if(x <= l && y >= r)
{
Add(value , l , r , k);
return;
}
int mid = (l + r) >> 1;
pushdown(value , l , mid , r , k);
if(x <= mid)
update(x , y , value , l , mid , k << 1);
if(y > mid)
update(x , y , value , mid + 1 , r , k << 1 | 1);
sum[k] = sum[k << 1] + sum[k << 1 | 1];
}
int main()
{
scanf("%d" , &t);
for(int tot = 1; tot <= t; tot++)
{
memset(sum , 0 , sizeof(sum));
memset(add , 0 , sizeof(add));
scanf("%d%d" , &n , &q);
build(1 , n , 1);
while(q--)
{
int x , y , value;
scanf("%d%d%d" , &x , &y , &value);
update(x , y , value , 1 , n , 1);
}
printf("Case %d: The total value of the hook is %lld.\n" , tot ,sum[1]);
}
return 0;
}