HDU 1698 Just a Hook [线段树-成段更新]

题意:


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



你可能感兴趣的:(HDU 1698 Just a Hook [线段树-成段更新])