这道题目就是考察的线段树求和的算法,比较简单。
注意事项:
1、如果一个区间的值都相同,则用cover=value标记;
2、如果区间的值原来都相同,现在要插入一个,则这个区间的cover值就为-1(用来标记这个区间的值不唯一)
3、最后求总和的时候,用count函数求和。
#include <iostream>
using namespace std;
struct Node
{
int r,l,mid,cover;
}node[350000];
void init(int a,int b,int num)
{
node[num].cover=1;
node[num].l=a;
node[num].r=b;
node[num].mid=(a+b)/2;
if(a==b)
return;
init(a,(a+b)/2,num*2);
init((a+b)/2+1,b,num*2+1);
}
void update(int a,int b,int value,int num)
{
//cout <<"fslfjd"<<endl;
if(node[num].cover==value)
return;
if(node[num].l==a && node[num].r==b)
{
node[num].cover=value;
return;
}
if(node[num].cover!=-1)
{
node[2*num].cover=node[num].cover;
node[num*2+1].cover=node[num].cover;
node[num].cover=-1;
}
if(b<=node[num].mid)
{
update(a,b,value,num*2);
}
else
{
if(a<=node[num].mid)
{
update(a,node[num].mid,value,2*num);
update(node[num].mid+1,b,value,2*num+1);
}
else
update(a,b,value,num*2+1);
}
}
int count(int num)
{
if(node[num].cover!=-1)
{
return (node[num].r-node[num].l+1)*node[num].cover;
}
else
return count(2*num)+count(2*num+1);
}
int main()
{
int ca;
cin >>ca;
for(int i=1;i<=ca;i++)
{
int n,m,a,b,c;
cin>>n>>m;
init(1,n,1);
for(int j=1;j<=m;j++)
{
scanf("%d%d%d",&a,&b,&c);
update(a,b,c,1);
}
cout <<"Case "<<i<<": The total value of the hook is "<<count(1)<<"."<<endl;
}
return 0;
}