题目链接:点击链接
题目大意是:
给一组棍子染色,不同的颜色有不同的值,执行一系列的区间染色后,问这组棍子的总值是多少。
思路:
lazy标记:就是更新时,不更新到最底层。
num表示线段树结点所代表区间的染色状况,如果该区间全为同样的颜色,则用1,2,3表示,如果含有多种颜色,则用-1表示。
每次执行染色操作时:
(1)如果所要染的颜色与区间颜色一样,则停止。
(2)如果所要染区间跟当前结点区间一致,则直接将所要染颜色赋给当前结点的num。
(3)如果当前结点区间不是混合色,则先将当前结点的颜色赋给左右子结点的num,并递归下去。
#include<stdio.h>
struct node
{
int left,right;
int num;
}s[400000];
int val;
void build(int start,int end,int n)
{
s[n].left = start;
s[n].right = end;
s[n].num = 1;
if(start == end)
return ;
int mid = (start + end) / 2;
build(start,mid, 2 * n );
build(mid + 1 ,end, 2 * n + 1);
}
void update(int start,int end,int n)
{
if(s[n].num == val) return ;
if(s[n].left == start && s[n].right == end)
{
s[n].num = val;
return ;
}
if(s[n].num != -1)
s[2 * n].num = s[2 * n + 1].num = s[n].num;
s[n].num = -1;
int mid = (s[n].left + s[n].right) / 2;
if(start > mid)
update(start,end,2 * n + 1);
else if(end <= mid)
update(start,end,2 * n);
else
{
update(start,mid,2 * n);
update(mid + 1,end, 2 * n + 1);
}
}
int sum(int n)
{
if(s[n].num != -1) return(s[n].right - s[n].left + 1) * s[n].num;
return sum(2 * n) + sum(2 * n +1);
}
int main()
{
int T,m,t,x,y,p = 1;
scanf("%d",&T);
while(T--)
{
scanf("%d",&m);
build(1,m,1);
scanf("%d",&t);
while(t--)
{
scanf("%d%d%d",&x,&y,&val);
update(x,y,1);
}
printf("Case %d: The total value of the hook is %d.\n",p ++,sum(1));
}
return 0;
}