http://acm.hdu.edu.cn/showproblem.php?pid=1698
题意:对n个hook进行区间3种涂色操作,初始时颜色都为1,求总和
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int NM=100005;
int T[NM*4],vau;
void Build(int lf,int rg,int rt)
{
T[rt]=1;
if(lf==rg) return;
int mid=(lf+rg)>>1;
Build(lf,mid,rt<<1);
Build(mid+1,rg,rt<<1|1);
}
void Update(int x,int y,int lf,int rg,int rt)
{
//区间值相同不用修改
if(T[rt]==vau) return;
//修改区间相同
if(lf==x&&rg==y){
T[rt]=vau;
return;
}
//区间为纯色,修改区域不一致时,现将子区域置为父值,在对子区域操作
if(T[rt]!=-1){
T[rt<<1]=T[rt<<1|1]=T[rt]; //迟缓更新(当区间值不再一致时,再更新)
T[rt]=-1;
}
//以下为父区间为杂色时的操作
int mid=(lf+rg)>>1;
if(x>mid) Update(x,y,mid+1,rg,rt<<1|1);
else if(y<=mid) Update(x,y,lf,mid,rt<<1);
else {
Update(x,mid,lf,mid,rt<<1);
Update(mid+1,y,mid+1,rg,rt<<1|1);
}
}
int Count(int lf,int rg,int rt)
{
if(T[rt]!=-1)
return (rg-lf+1)*T[rt];
else {
int mid=(lf+rg)>>1;
return Count(lf,mid,rt<<1)+Count(mid+1,rg,rt<<1|1);
}
}
int main()
{
int T,i,n,m,x,y;
scanf("%d",&T);
for(i=1;i<=T;i++)
{
scanf("%d%d",&n,&m);
Build(1,n,1);
while(m--)
{
scanf("%d%d%d",&x,&y,&vau);
Update(x,y,1,n,1);
}
printf("Case %d: The total value of the hook is %d.\n",i,Count(1,n,1));
}
return 0;
}