3、屠夫的钩子
源程序名 hook.cpp
可执行文件名 hook.exe
输入文件名 hook.in
输出文件名 hook.out
时限3s
内存 256MB
描述
在DotA游戏中,屠夫的钩子是英雄们非常惧怕的武器之一,钩子是由N段连续的金属棒构成,一开始钩子的每段金属棒材质均为铜,现在屠夫想增强他武器的威力,决定对他的钩子进行改造,由于智商问题,他一次只能将连续的一段金属棒的的材质变为成金、银、铜的一种,每种材质的一段金属棒的攻击力分别为3,2,1,屠夫想知道按照一系列升级后,他的武器总攻击力为多少,即每个金属棒攻击力之和。
输入
第一行一个数T,表示由T组测试数据。
对于每组数据,第一行一个数N,表示屠夫的钩子的共有N段金属棒,第二行一个数Q,表示屠夫对他的钩子进行了Q次改造,接下来Q行,每行3个数x,y,z,表示屠夫将[x,y]段金属的材质变为z。z=1,表示铜,z=2表示银,z=3表示金。
输出
对于每组测试数据输出改造后的钩子的攻击力,注意使用样例中的格式,各占一行。
样例
hook.in
1
10
2
1 5 2
5 9 3
hook.out
Case 1: The total value of the hook is 24.
数据范围
1<=T<=10
1<=N,Q<=100000
1<=x,y<=N,1<=z<=3
#include<iostream>
#include<cstdio>
using namespace std;
const int maxn=100001;
int add[4*maxn],sum[4*maxn];//数组必须4倍 好像是因为树是2的平方
void pushup(int x)
{
sum[x]=sum[x*2]+sum[x*2+1];
}
void pushdown(int rt,int m)
{
if(add[rt])
{
add[rt*2]=add[rt];
add[rt*2+1]=add[rt];
sum[rt*2]=add[rt]*(m-m/2);
sum[rt*2+1]=add[rt]*(m/2);
add[rt]=0;
}
}
void build(int l,int r,int rt)
{
add[rt]=0;
if(l==r)
{
sum[rt]=1;
return ;
}
int m=(l+r)/2;
build(l,m,rt*2);
build(m+1,r,rt*2+1);
pushup(rt);
}
void update(int L,int R,int c,int l,int r,int rt)
{
if(L<=l&&r<=R)
{
add[rt]=c;
sum[rt]=(r-l+1)*c;
return ;
}
pushdown(rt,r-l+1);
int m=(l+r)/2;
if(L<=m)update(L,R,c,l,m,rt*2);
if(R>m)update(L,R,c,m+1,r,rt*2+1);
pushup(rt);
}
int query(int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R)return sum[rt];
pushdown(rt,r-l+1);
int m=(l+r)/2;
int ret=0;
if(L<=m)ret+=query(L,R,l,m,rt*2);
if(R>m)ret+=query(L,R,m+1,r,rt*2+1);
return ret;
}
int main()
{freopen("hook.in","r",stdin);
freopen("hook.out","w",stdout);
int t,k=0,n,m,q,x,y,v;
scanf("%d",&t);
while(++k<=t)
{
scanf("%d",&n);
getchar();
scanf("%d",&m);
build(1,1,n);
update(1,n,1,1,n,1);
for(int i=0;i<m;i++)
{
scanf("%d%d%d",&x,&y,&v);//不能cin cout 会超时 加了ios_sy崩溃
getchar();
update(x,y,v,1,n,1);
}
printf("Case %d: The total value of the hook is %d.\n",k,query(1,n,1,n,1));
}
return 0;
}