问题描述
在 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;
}