HDU P1698 Just a Hook【线段树】

题目不难,但是由于此处的标记感觉十分巧妙,所以提一下。

容易发现我们在涂色的时候会出现某一段区间的颜色有多种的的情况,这个时候我们用一个类似于 L a z y 的标记 C o l o r 标记一下,如果 C o l o r == 1 说明此段区间颜色不唯一,否则颜色唯一。而我们在查询的时候避开 C o l o r == 1 的情况搜索左儿子右儿子即可。

参考代码:

#include <bits/stdc++.h>
using namespace std;
const int Max=1e5+5;
const int Inf=1e9;
struct Node{
    int X,Y,Color;
}Tree[Max<<3];
int T,N,M;
void MakeTree(int P,int X,int Y){
    Tree[P].X=X;Tree[P].Y=Y;Tree[P].Color=1;
    if(X<Y){
        MakeTree(P<<1,X,X+Y>>1);
        MakeTree(P<<1|1,(X+Y>>1)+1,Y);
    }
}
void Update(int P,int X,int Y,int Z){
    if(X==Tree[P].X&&Y==Tree[P].Y){
        Tree[P].Color=Z;return ;
    }
    if(Tree[P].Color==Z){
        return ;
    }
    if(Tree[P].Color!=-1){
        Tree[P<<1].Color=Tree[P].Color;
        Tree[P<<1|1].Color=Tree[P].Color;Tree[P].Color=-1;
    }
    if(Tree[P<<1|1].X<=X){
        Update(P<<1|1,X,Y,Z);
    } else if (Y<=Tree[P<<1].Y){
        Update(P<<1,X,Y,Z);
    } else {
        Update(P<<1,X,Tree[P<<1].Y,Z);
        Update(P<<1|1,Tree[P<<1|1].X,Y,Z);
    }
}
int GetSum(int P){
    if(Tree[P].Color!=-1){
        return Tree[P].Color*(Tree[P].Y+1-Tree[P].X);
    }
    return GetSum(P<<1)+GetSum(P<<1|1);
}
int main(){
    int I,J,K;
    scanf("%d",&T);
    for(K=1;K<=T;K++){
        scanf("%d%d",&N,&M);
        MakeTree(1,1,N);
        for(I=1;I<=M;I++){
            int X,Y,Z;
            scanf("%d%d%d",&X,&Y,&Z);
            Update(1,X,Y,Z);
        }
        printf("Case %d: The total value of the hook is %d.\n",K,GetSum(1));
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/yanzhenhuai/article/details/81252647