题意:成段覆盖染色,求颜色值的总和。
思路:线段树水题。成段更新,最后求和。我写的最顺利的线段树,从头到尾代码一气呵成,没用模板,一次AC,过瘾,不过美中不足的是运行时间有点慢。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int MAXN=100003;
int sum;
inline int MID(int l,int r){return (l+r)>>1;}
inline int L(int r){return r<<1;}
inline int R(int r){return (r<<1)+1;}
typedef struct
{
int left,right;
int value;
}LINE;
LINE tree[MAXN*4];
void Create(int l,int r,int root)
{
tree[root].left=l;
tree[root].right=r;
tree[root].value=1;
if(l==r) return;
int mid=MID(l,r);
Create(l,mid,L(root));
Create(mid+1,r,R(root));
}
void Update(int l,int r,int v,int root)
{
if(l<=tree[root].left&&tree[root].right<=r)
{
tree[root].value=v;
return;
}
if(tree[root].value==v)return;
if(tree[root].left==tree[root].right)return;
if(tree[root].value>0)
{
tree[L(root)].value=tree[root].value;
tree[R(root)].value=tree[root].value;
tree[root].value=0;
}
int mid=MID(tree[root].left,tree[root].right);
if(l>mid) Update(l,r,v,R(root));
else if(r<=mid) Update(l,r,v,L(root));
else
{
Update(l,mid,v,L(root));
Update(mid+1,r,v,R(root));
}
}
void Solve(int l,int r,int root)
{
if(tree[root].value>0)
{
sum+=tree[root].value*(r-l+1);
return;
}
if(tree[root].left==tree[root].right) return;
int mid=MID(l,r);
Solve(l,mid,L(root));
Solve(mid+1,r,R(root));
}
int main()
{
int cnt=1;
int t,N,Q;
scanf("%d",&t);
while(t--)
{
scanf("%d",&N);
scanf("%d",&Q);
Create(1,N,1);
int l,r,v;
for(int i=0;i<Q;i++)
{
scanf("%d %d %d",&l,&r,&v);
Update(l,r,v,1);
}
sum=0;
Solve(1,N,1);
printf("Case %d: The total value of the hook is %d.\n",cnt++,sum);
}
return 0;
}