计蒜客习题:帕吉的肉钩

问题描述

在 DotA 游戏中,帕吉的肉钩是很多英雄最害怕的东西。钩子由连续若干段的等长金属棒制成。
现在帕吉对钩子由一些操作:
我们将金属棒 1~n 依次编号,帕吉可以把编号 x~y 的金属棒变成铜棒、银棒、金棒。
每段铜棒的价值是 1;每段银棒的价值是 2;每段金棒的价值是 3。
肉钩的总价值是 n 段金属棒价值之和。
帕吉想知道若干操作以后钩子的总价值。
输入格式
第一行一个整数 N(1≤N≤10^5),表示肉钩金属棒的数量,初始状态为 铜棒。
第二行一个整数 Q(1≤Q≤10^5),表示操作数。
接下来 Q 行,一行三个整数,X,Y,Z(1≤X≤Y≤N,1≤Z≤3)
输出格式
一行一个整数,表示钩子的总价值,用样例中的格式。
样例输入

10
2
1 5 2
5 9 3

样例输出

The total value of the hook is 24.

AC代码

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int MAX_N=(1e5)+50;
int p[MAX_N*4];
int col[MAX_N*4];

void up(int n){
    p[n]=p[n*2]+p[n*2+1];
    return;
}

void down(int n,int l,int r){
    if(col[n]){
        int mid=(l+r)/2;
        p[n*2]=col[n]*(mid-l+1);
        p[n*2+1]=col[n]*(r-mid);
        col[n*2+1]=col[n];
        col[n*2]=col[n];
        col[n]=0;
    }
}

void molify(int n,int l,int r,int x,int y,int v){
    if(x<=l&&y>=r){
        col[n]=v;
        p[n]=v*(r-l+1);
        return;
    }
    down(n,l,r);
    int mid=(l+r)/2;
    if(x<=mid)molify(n*2,l,mid,x,y,v);
    if(y>mid)molify(n*2+1,mid+1,r,x,y,v);
    up(n);
    return ;
}

long long int query(int n,int l,int r,int x,int y){
    if(x<=l&&y>=r)return p[n];
    down(n,l,r);
    long long int res=0;
    int mid=(l+r)/2;
    if(x<=mid)res+=query(n*2,l,mid,x,y);
    if(y>mid)res+=query(n*2+1,mid+1,r,x,y);
    return res;
}


int main(){
    int N,Q;
    cin>>N>>Q;
    memset(col,0,sizeof(col));
    molify(1,1,N,1,N,1);
    for(int i=1;i<=Q;i++){
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z); 
        molify(1,1,N,x,y,z);
    }

    cout<<"The total value of the hook is "<<query(1,1,N,1,N)<<".";
    return 0;
}

猜你喜欢

转载自blog.csdn.net/liukairui/article/details/80905552