一个小小的点拖了这么久,好在终于考完试了,能好好做会题了。
这题也没自己写了,抄了一份模板。(写的确实比自己好。。)
#include<cstdio>
#include<algorithm>
#include<iostream>
using namespace std;
#define lchild rt << 1, l, m
#define rchild rt << 1 | 1, m + 1, r
const int N=400010;
int tree[N],lazy[N],t,ans=1,L,R,delta,n,m;
void push_down(int rt, int len) {
if(lazy[rt])
{
lazy[rt << 1]=lazy[rt << 1 | 1] = lazy[rt];/*延迟标记往下传*/
tree[rt << 1] = lazy[rt << 1] * (len - (len >> 1));/*左子树比右子树多1*/
tree[rt << 1 | 1] = lazy[rt << 1 | 1] * (len >> 1);
lazy[rt] = 0; /*往下传完就赋0*/
}
}
void build(int rt, int l, int r) {
lazy[rt]=0; /*建树先将延迟标标为0*/
if (l == r) {
tree[rt]=1;
return;
}//注意对树的初始赋值
int m = (l + r) >> 1;
build(lchild); build(rchild);
tree[rt]=tree[rt << 1]+tree[rt << 1 | 1];/*每个节点为两子节点之和*/
}
/*数据更新,这个算法在于不用每次更新到最底部,更新到对应区间的节点即可,等下次更新时再往下传递*/
void update(int rt, int l, int r) {
if (L <= l && r <= R) {
tree[rt] = delta * (r - l + 1);
lazy[rt] = delta;/*这个区间需要加的数先记录,需要时再往下加,大大减少操作*/
return;
}
push_down(rt, r - l + 1);
int m = (l + r) >> 1;
if (L <= m) update(lchild);
if (R > m) update(rchild);
tree[rt]=tree[rt << 1]+tree[rt << 1 | 1];
}
int main()
{
for(scanf("%d",&t);t--;)
{
scanf("%d%d",&n,&m);
build(1,1,n);
for(int i=0;i<m;i++)
{
scanf("%d%d%d",&L,&R,&delta);
update(1,1,n);
}
printf("Case %d: The total value of the hook is %d.\n",ans++,tree[1]);
}
}