题意:屠夫有一条长的钩子,钩子由n个小钩子组成,每次操作将一个区间的小钩子变成金(3)银(2)铜(1)三者之一,最后取出所有区间的钩子总长度
思路:区间置换好区间跟新一个思考,简单的区间更新;
AC code:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long LL;
#define N 1000100
struct node
{
LL l;
LL r;
LL sum;
LL lazy; //lazy标记记录更新值
}tree[N << 2];
void pushdown(LL root, LL len)
{
if (tree[root].lazy)
{ //更新子区间标记
tree[root * 2].lazy = tree[root].lazy;
tree[root * 2 + 1].lazy = tree[root].lazy; //更新子区间和
tree[root * 2].sum = tree[root].lazy*(len - (len / 2));
tree[root * 2 + 1].sum = tree[root].lazy*(len / 2);
tree[root].lazy = 0; //lazy标记清零
}
}
void build(LL root, LL l, LL r)
{
tree[root].l = l;
tree[root].r = r;
tree[root].lazy = 0; //初始化lazy
if (l == r)
{
tree[root].sum = 1; // 钩子最初全为铜
return;
}
LL mid = (tree[root].l + tree[root].r) / 2;
build(root * 2, l, mid);
build(root * 2 + 1, mid + 1, r);
tree[root].sum = tree[root * 2].sum + tree[root * 2 + 1].sum;
}
void update(LL root, LL l, LL r, LL c)
{
if (l <= tree[root].l &&tree[root].r <= r)
{
tree[root].lazy = c; //更新最大区间的lazy标记,用的时候才传递 防止超时
tree[root].sum = c*(tree[root].r - tree[root].l + 1); //同时维护sum
return;
}
pushdown(root, tree[root].r - tree[root].l + 1); //更新儿子节点的标记,防止二次更新使区间和,lazy标记被覆盖
LL mid = (tree[root].l + tree[root].r) / 2;
if (l <= mid)
{
update(root * 2, l, r, c);
}
if (r > mid)
{
update(root * 2 + 1, l, r, c);
}
tree[root].sum = tree[root * 2].sum + tree[root * 2 + 1].sum;
}
LL query(LL root, LL l, LL r)
{
LL ans = 0;
LL mid = (tree[root].l + tree[root].r) / 2;
if (l <= tree[root].l &&tree[root].r <= r)
{
return tree[root].sum;
}
pushdown(root, tree[root].r - tree[root].l + 1); //将父亲的lazy标记传递下去,更新儿子节点,维护查找的区间和准确
if (l <= mid)
{
ans += query(root * 2, l, r);
}
if (r > mid)
{
ans += query(root * 2 + 1, l, r);
}
tree[root].sum = tree[root * 2].sum + tree[root * 2 + 1].sum;
return ans;
}
int main()
{
LL i, x, y, z, n, m, t, k = 1;
scanf("%lld", &t);
while (t--)
{
scanf("%lld", &n);
build(1, 1, n);
scanf("%lld", &m);
for (i = 1; i <= m; i++)
{
scanf("%lld%lld%lld", &x, &y, &z);
update(1, x, y, z);
}
printf("Case %lld: The total value of the hook is %lld.\n", k++, query(1, 1, n));
}
return 0;
}