Just a Hook
本来还以为这道题是区间修改,但是发现,区间修改在这道题上不能照搬
区间修改为知道某一区间的修改值
而这道题未知,只知道修改到最后的值
重点是这道题求总值,不是求一段区间的价值
那么这道题就更好做了。
根本就不用考虑下面的值的情况,这道题只用到了总区间
所以比区间修改简单多了
AC代码
#include <iostream>
#include<algorithm>
#include<queue>
#include<cmath>
#include<string.h>
#include<stdio.h>
#include<stdlib.h>
using namespace std;
const int maxn = 111111;
int h, w, n;
int col[maxn<<2];//记录区间的价值
int sum[maxn<<2];//记录区间的值
void PushDown(int root,int m)//m表示改值的区间长度
{
if (col[root])
{
col[root<<1] = col[root<<1|1] = col[root];//将区间价值传给子区间,下面两步为计算子区间价值
sum[root<<1] = (m - (m >> 1)) * col[root];//长度和 (l+r)/2-l一样即(r-l+1)-(r-l+1)/2==(l+r)/2-l
sum[root<<1|1] = (m >> 1) * col[root]; //计算子区间的价值
col[root] = 0; //计算完子区间价值就可以清零了(不清零也没事)
}
}
void cre(int l,int r,int root) //创建线段树
{
col[root]=0;
sum[root]=1;
if(l==r)
return;
int mid= (l+r)>>1;
cre(l,mid,root<<1);
cre(mid+1,r,root<<1|1);
sum[root] = sum[root<<1] + sum[root<<1|1];
}
void upd(int L,int R,int c,int l,int r,int root)//l,r表示修改的区间
{
if(L<=l&&r<=R)
{
col[root]=c;//如果区间相等把价值存下来
sum[root]=c*(r-l+1);//总值变为价值乘以长度
return ;
}
PushDown(root,r-l+1);//向下求子区间的值为的是可以用子区间的值来更新这个区间值
int mid =(l+r)>>1;
if(L<=mid)
upd(L,R,c,l,mid,root<<1);
if(R>mid)
upd(L,R,c,mid+1,r,root<<1|1);
sum[root] = sum[root<<1] + sum[root<<1|1];
}
int main()
{
int T, n, m;
scanf("%d",&T);
for (int cas = 1 ; cas <= T ; cas ++)
{
scanf("%d%d",&n,&m);
cre(1, n, 1);
while (m --)
{
int a, b, c;
scanf("%d%d%d",&a,&b,&c);
upd(a, b, c, 1, n, 1);
}
printf("Case %d: The total value of the hook is %d.\n",cas, sum[1]);
}
return 0;
}