线段树成段更新。
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <string>
using namespace std;
const int maxn = 1000010;
const int INF = 0x3f3f3f3f;
int n, m;
int p, v;
int y1, y2;
int sumv[maxn<<2], minv[maxn<<2], maxv[maxn<<2];
int setv[maxn<<2];
void pushup(int o)
{
sumv[o] = sumv[o*2] + sumv[o*2+1];
}
void build(int o, int L, int R)
{
int lc = o*2, rc = o*2+1;
setv[o] = -1;
sumv[o] = 1;
if(L == R) return ;
int M = L + (R-L)/2;
build(lc, L, M);
build(rc, M+1, R);
pushup(o);
}
void maintain(int o, int L, int R)
{
int lc = o*2, rc = o*2+1;
if(R > L)
{
sumv[o] = sumv[lc] + sumv[rc];
minv[o] = min(minv[lc], minv[rc]);
maxv[o] = max(maxv[lc], maxv[rc]);
}
if(setv[o] >= 0) { minv[o] = maxv[o] = setv[o]; sumv[o] = setv[o] * (R-L+1);}
}
void pushdown(int o)
{
int lc = 2*o, rc = 2*o+1;
if(setv[o] >= 0)
{
setv[lc] = setv[rc] = setv[o];
setv[o] = -1;
}
}
void update(int o, int L, int R)
{
int lc = 2*o, rc = 2*o+1;
if(y1 <= L && y2 >= R)
{
setv[o] = v;
}
else
{
pushdown(o);
int M = L + (R-L)/2;
if(y1 <= M) update(lc, L, M); else maintain(lc, L, M);
if(y2 > M) update(rc, M+1, R); else maintain(rc, M+1, R);
}
maintain(o, L, R);
}
int _sum, _min, _max;
void query(int o, int L, int R)
{
int lc = o*2, rc = o*2+1;
if(setv[o] >= 0)
{
_sum += setv[o] * (min(R, y2) - max(L, y1) + 1);
_min = min(_min, setv[o]);
_max = max(_max, setv[o]);
}
else if(y1 <= L && y2 >= R)
{
_sum += sumv[o];
_min = min(_min, minv[o]);
_max = max(_max, maxv[o]);
}
else
{
int M = L + (R-L)/2;
if(y1 <= M) query(lc, L, M);
if(y2 > M) query(rc, M+1, R);
}
}
void read_case()
{
scanf("%d", &n);
scanf("%d", &m);
build(1, 1, n);
while(m--)
{
scanf("%d%d%d", &y1, &y2, &v);
update(1, 1, n);
}
}
void solve()
{
read_case();
y1 = 1, y2 = n;
_min = INF, _max = -INF, _sum = 0;
query(1, 1, n);
printf("The total value of the hook is %d.\n", _sum);
}
int main()
{
int T, times = 0;
scanf("%d", &T);
while(T--)
{
printf("Case %d: ", ++times);
solve();
}
return 0;
}