HDU-1698-Just a Hook(区间染色 并求和)

题目
现在,Pudge想在钩子上做一些操作。
让我们将钩子上连续的金属棒编号从1到n,每一次操作,Pudge都可以将编号从X到Y的连续金属棒改为铜棒、银棒或金棒。该钩的总价值计算为N根金属杆的总价值之和。更准确地说,每一种棍的值计算如下:对于每根铜棒,值是1。对于每根银棒,值是2。每根金棒的值是3。
Pudge想知道执行操作后钩子的总价值。你可以认为原来的钩子是用铜棒做的。

输入

输入由几个测试用例组成。输入的第一行是案例的数量。不超过10例。
对于每一种情况,第一行包含一个整数N, 1<=N<=100,000,这是Pudge’s meat hook的棍子数,第二行包含一个整数Q, 0<=Q<=100,000,这是操作数。
接下来的Q行,每行包含3个整数X, Y, 1<=X<=Y<=N, Z, 1<=Z<=3,定义了一个操作:将编号为X到Y的木棍改为金属型Z,其中Z=1表示铜类,Z=2表示银类,Z=3表示金类。

Sample Input

1
10
2
1 5 2
5 9 3

Sample Output

Case 1: The total value of the hook is 24.

emmm。区间染色 tag不需要上推。不管tag!=-1与否 都是要强行染色的。

#include <cstdio>
using namespace std;
const int N=100005*4;
int sum[N],tag[N];
void pushup(int pos)
{
    sum[pos]=sum[pos<<1]+sum[pos<<1|1];
}
void build(int l,int r,int pos)
{
    if(l==r)
    {
        tag[pos]=1;
        sum[pos]=1;
        return;
    }
    int mid=(l+r)>>1;
    build(l,mid,pos<<1);
    build(mid+1,r,pos<<1|1);
    tag[pos]=1;
    pushup(pos);
}
void pushdown(int ln,int rn,int pos)
{
    if(tag[pos]==-1)
        return;
    tag[pos<<1]=tag[pos<<1|1]=tag[pos];
    sum[pos<<1]=ln*tag[pos];
    sum[pos<<1|1]=rn*tag[pos];
    tag[pos]=-1;
}
void chanspan(int cl,int cr,int val,int l,int r,int pos)
{
    if(cl<=l&&r<=cr)
    {
        tag[pos]=val;
        sum[pos]=val*(r-l+1);
        return;
    }
    int mid=(l+r)>>1;
    pushdown(mid-l+1,r-mid,pos);
    if(cl<=mid)
        chanspan(cl,cr,val,l,mid,pos<<1);
    if(cr>mid)
        chanspan(cl,cr,val,mid+1,r,pos<<1|1);
    pushup(pos);
}
int main()
{
    int T;
    scanf("%d",&T);
    int cas=0;
    while(T--)
    {
        ++cas;
        int n;
        scanf("%d",&n);
        build(1,n,1);
        int q;
        scanf("%d",&q);
        while(q--)
        {
            int a,b,z;
            scanf("%d%d%d",&a,&b,&z);
            chanspan(a,b,z,1,n,1);
        }
        printf("Case %d: The total value of the hook is %d.\n",cas,sum[1]);
    }
}

猜你喜欢

转载自blog.csdn.net/qq_42576687/article/details/87891550