简单的线段树区间更新。区间求和。莫名奇妙的是 数组要开3*N才能过。坑了好久。
#include<stdio.h>
#include<string.h>
#include<iostream>
#define maxn 300000 + 10
using namespace std;
int val[maxn];
struct Tree
{
int mark;
int total;
int left, right;
}tree[maxn*4];
int create(int root, int left, int right) // 以root为根节点建树。
{
tree[root].mark = 0;
tree[root].left = left;
tree[root].right = right;
if (left == right)
return tree[root].total = val[left];
int mid = (left + right) / 2;
int a, b;
a = create(2*root, left, mid);
b = create(2*root+1, mid+1, right);
return tree[root].total = a + b;
}
void update_mark(int root)
{
if (tree[root].mark)
{
tree[root].total = tree[root].mark * (tree[root].right - tree[root].left + 1);
if (tree[root].left != tree[root].right)
tree[root*2].mark = tree[root*2+1].mark = tree[root].mark;
tree[root].mark = 0;
}
}
int update(int root, int left, int right, int val) // 区间更新
{
update_mark(root);
if (tree[root].left > right || tree[root].right < left) // 当前区间和更新区间无交集。不作处理。
return tree[root].total;
if (left <= tree[root].left && tree[root].right <= right) // 没动延迟标记咋用的.这是当前区间完全包含在更新区间的时候。
{
tree[root].mark = val;
return tree[root].total = val * (tree[root].right - tree[root].left + 1);
}
int a = update(2*root, left, right, val);
int b = update(2*root+1, left, right, val);
return tree[root].total = a + b;
}
int calculate(int root, int left, int right) // 求区间和
{
update_mark(root);
if (tree[root].left > right || tree[root].right < left)
return 0;
if (left <= tree[root].left && tree[root].right <= right)
return tree[root].total;
int a = calculate(2*root, left, right);
int b = calculate(2*root+1, left, right);
return a + b;
}
int main()
{
int t, n, q;
scanf("%d", &t);
int cnt = 0;
while(t--)
{
cnt++;
scanf("%d%d", &n, &q);
for (int i=1; i<=n; ++i)
val[i] = 1;
create(1, 1, n);
for (int i=0; i<q; ++i)
{
int x, y, te;
scanf("%d%d%d", &x, &y, &te);
update(1, x, y, te);
}
int ans = calculate(1, 1, n);
printf("Case %d: The total value of the hook is %d.\n", cnt, ans);
}
return 0;
}