题意:
屠夫的钩子,可以理解成一条线段,[x,y]是某种颜色,铜色的价值是1,银色是2,金色是3,经过一系列的更新操作,求总的value
分析:
参考比人的,第一次做线段树,找点感觉
记录每个区间是否为纯色,即cover,1为纯色,0为混合色
//AC CODE:
#include<iostream>
#include<cstdio>
using namespace std;
const int MAXN=300005;
struct Node
{
int left,right;
int value; //用来记录每个节点的值
int isCover; //用来标记是否已经修改过
}tree[MAXN];
void MakeTree(int l,int r,int num)//建树
{
int mid;
tree[num].left=l;
tree[num].right=r;
tree[num].value=1;
tree[num].isCover=1;
if(l==r) //点树
return;
mid=(l+r)>>1;
MakeTree(l,mid,num*2);//递归的建左子树树
MakeTree(mid+1,r,num*2+1);//递归的建右子树
}
void modify(int x,int y,int z,int num)//更新
{
if(x==tree[num].left && y==tree[num].right)
{
tree[num].value=z; //赋值
tree[num].isCover=1; //标记是否被修改
return;
}
if(tree[num].isCover)
{
tree[num].isCover=0;
tree[2*num].value=tree[num].value;
tree[2*num].isCover=1;
tree[2*num+1].value=tree[num].value;
tree[2*num+1].isCover=1;
}
if(y<=tree[2*num].right)
modify(x,y,z,2*num);
else if(x>=tree[2*num+1].left)
modify(x,y,z,2*num+1);
else
{
modify(x,tree[2*num].right,z,2*num);
modify(tree[2*num+1].left,y,z,2*num+1);
}
}
int Query(int num)//查询
{
if(tree[num].isCover)
return tree[num].value*(tree[num].right-tree[num].left+1);
else
return Query(2*num)+Query(2*num+1);
}
int main()
{
//freopen("in.txt","r",stdin);
int test;
int n,q;
int x,y,z;
int i=1;
scanf("%d",&test);
for(i=1; i<=test; i++)
{
scanf("%d",&n);
scanf("%d",&q);
MakeTree(1,n,1); //建树(1 to n)
while(q--)
{
scanf("%d %d %d",&x,&y,&z);
modify(x,y,z,1);
}
printf("Case %d: The total value of the hook is %d.\n",i,Query(1));
}
return 0;
}