题意
有m个钩子,初始的时候钩子都是铜钩子,伤害为1,然后有n种操作,每个操作有三个数,l,r,c表示讲从l到r的钩子的价值换成c,最后输出所有钩子的价值总和
样例
Sample Input
1
10
2
1 5 2
5 9 3
Sample Output
Case 1: The total value of the hook is 24.
AC代码
#include <iostream>
#include <string>
#include <map>
#include <cstdio>
using namespace std;
int tree[400001];
int lazy[400001];
int n,m;
void build(int l,int r,int t)
{
lazy[t] = 1;//初值为铜
tree[t] = r - l + 1;//初始化区间和
if(l == r)return;
int mid = (l + r) >> 1;
build(l,mid,t << 1);
build(mid + 1,r,t << 1 | 1);
}
void update(int L,int R,int val,int l,int r,int t)
{
if(L <= l && R >= r)///区间在要求改变的范围内改变区间总和,并改变对应的lazy为val,不继续深入并返回
{
lazy[t] = val;
tree[t] = (r - l + 1) * val;
return;
}
int mid = (l + r) >> 1;
if(lazy[t])///区间不被要求的范围所包含,需要向下更新。
{
lazy[t << 1] = lazy[t << 1 | 1] = lazy[t];
tree[t << 1] = lazy[t] * (mid - l + 1);//区间和进行分割向下分配
tree[t << 1 | 1] = lazy[t] * (r - mid);//区间和进行分割向下分配
lazy[t] = 0;//lazy归零
}
if(R <= mid)update(L,R,val,l,mid,t << 1);
else if(L > mid)update(L,R,val,mid + 1,r,t << 1 | 1);
else
{
update(L,mid,val,l,mid,t << 1);
update(mid + 1,R,val,mid + 1,r,t << 1 | 1);
}
tree[t] = tree[t << 1] + tree[t << 1 | 1];///向上更新
}
int main()
{
int t,a,b,c;
scanf("%d",&t);
for(int i = 1;i <= t;i ++)
{
scanf("%d%d",&n,&m);//用scanf耗时少
build(1,n,1);
for(int j = 0;j < m;j ++)
{
scanf("%d%d%d",&a,&b,&c);
update(a,b,c,1,n,1);
}
printf("Case %d: The total value of the hook is %d.\n",i,tree[1]);
}
}
题源:acm.hdu.edu.cn/showproblem…