成段更新 + LAZY操作
#include "stdio.h"
#include "string.h"
#include "math.h"
#include "stdlib.h"
struct comp
{
int l,r,mid,x;
} data[300001];
int ans;
void build(int l,int r,int k)
{
data[k].l=l;
data[k].r=r;
data[k].mid=(l+r)/2;
data[k].x=1; //记录所染颜色,-1代表混合
if (l==r) return ;
build(l,data[k].mid,2*k);
build(data[k].mid+1,r,2*k+1);
}
void update(int l,int r,int k,int op)
{
if (data[k].x==op) return ; // 没有此优化会超时
if (data[k].l==l && data[k].r==r )
{
data[k].x=op;
return ;
}
if (data[k].x!=-1) // LAZY 操作的向下更新
{
if (l<=data[k].mid+1 && l>data[k].l) update(data[k].l,l-1,k*2,data[k].x);
if (l>data[k].mid+1)
{
update(data[k].l,data[k].mid,k*2,data[k].x);
update(data[k].mid+1,l-1,k*2+1,data[k].x);
}
if (r>=data[k].mid && r<data[k].r) update(r+1,data[k].r,k*2+1,data[k].x);
if (r<data[k].mid)
{
update(r+1,data[k].mid,k*2,data[k].x);
update(data[k].mid+1,data[k].r,k*2+1,data[k].x);
}
}
if (r<=data[k].mid)
update(l,r,k*2,op);
else
if (l>data[k].mid)
update(l,r,k*2+1,op);
else
{
update(l,data[k].mid,2*k,op);
update(data[k].mid+1,r,2*k+1,op);
}
if (data[k*2].x==data[k*2+1].x && data[k*2].x!=-1)
data[k].x=data[k*2].x;
else
data[k].x=-1;
}
void search(int k)
{
if (data[k].x!=-1)
{
ans+=data[k].x*(data[k].r-data[k].l+1);
return ;
}
search(k*2);
search(k*2+1);
}
int main()
{
int t,ii,n,m,a,b,c;
scanf("%d",&t);
for (ii=1;ii<=t;ii++)
{
scanf("%d",&n);
build(1,n,1);
scanf("%d",&m);
while (m--)
{
scanf("%d%d%d",&a,&b,&c);
update(a,b,1,c);
}
ans=0;
search(1);
printf("Case %d: The total value of the hook is %d.\n",ii,ans);
}
return 0;
}