题意:
屠夫的钩子,可以理解成一条线段,[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; }