注意,
1 ,区间查询写错,ll,rr和m的比较
2 ,lazy 标记算的长度在右区间不用加1
更新分析,如果把线段树的每个点都更新,线段树就不再有logn的优势,所以有用一个标记表示在这个区间内有需要更新的,等你查询要用时再重新更新,
#include<iostream>
#include<cstdio>
using namespace std;
#define L l,m,u<<1
#define R m+1,r,u<<1|1
const int N = 111111;
struct node
{
int seg, s;
}num[N * 4];
void push(int u)
{
num[u].s = num[u << 1].s + num[u << 1 | 1].s;
}
void pushdown(int l, int r, int u)
{
num[u << 1].seg = num[u << 1 | 1].seg = num[u].seg;
int m = (l + r) >> 1;
//left tree
num[u << 1].s = (m - l + 1)*num[u].seg;
// right tree
num[u << 1 | 1].s = (r - m )*num[u].seg;//之前多加一个1 wa好多发
num[u].seg = -1;
}
void build(int l, int r, int u)
{
num[u].seg = -1;
if (l == r)
{
num[u].s = 1;
return;
}
int m = (l + r) >> 1;
build(L);
build(R);
push(u);
}
void update(int ll, int rr, int x, int l, int r, int u)
{
//if (num[u].s == x) return;
if ( ll<=l&&r <= rr)
{
num[u].seg = x;
num[u].s = (r - l + 1)*x;
return;
}
if (num[u].seg != -1) pushdown(l, r, u);
int m = (l + r) >> 1;
if (ll <= m)
update(ll, rr, x, L);
if (rr>m)
update(ll, rr, x, R);
push(u);
}
int querry(int ll,int rr,int l, int r, int u)
{
if (l >= ll&&r <= rr)
{
return num[u].s;
}
if (num[u].seg == -1)
pushdown(l, r, u);
int m = (l + r) >> 1, sum = 0;
if (ll <= m)
sum+=querry(ll, rr, L);
if (rr > m) sum += querry(ll, rr, R);
return sum;
}
int main()
{
int t, i, j;
while(cin >> t)
{
for (int ca = 1; ca <= t; ca++)
{
int n, q;
scanf("%d%d", &n, &q);
build(1, n, 1);
while (q--)
{
int l, r, x;
scanf("%d%d%d", &l, &r, &x);
// puts("intput");
//cout << l << " " << r << " " << x << endl;
update(l, r, x, 1, n, 1);
}
printf("Case %d: The total value of the hook is %d.\n", ca, querry(1,n,1,n,1));
}
}
return 0;
}
/*#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
const int maxn = 100005;
int t, n, q;
ll sum[maxn * 4], add[maxn * 4];
void pushup(int rt) {
sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
}
void pushdown(int rt, int len) {
if (add[rt]) {
add[rt << 1] = add[rt];
add[rt << 1 | 1] = add[rt];
sum[rt << 1] = add[rt] * (len - (len >> 1));
sum[rt << 1 | 1] = add[rt] * (len >> 1);
add[rt] = 0;
}
}
void build(int l, int r, int rt) {
add[rt] = 0;
if (l == r) {
//scanf("%I64d",&sum[rt]);
sum[rt] = 1;
return;
}
int m = (l + r) >> 1;
build(l, m, rt << 1);
build(m + 1, r, rt << 1 | 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] = (ll)c*(r - l + 1);
return;
}
pushdown(rt, r - l + 1);
int m = (l + r) >> 1;
if (L <= m) update(L, R, c, l, m, rt << 1);
if (R>m) update(L, R, c, m + 1, r, rt << 1 | 1);
pushup(rt);
}
ll querry(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) >> 1;
ll ans = 0;
if (L <= m) ans += querry(L, R, l, m, rt << 1);
if (R>m) ans += querry(L, R, m + 1, r, rt << 1 | 1);
return ans;
}
int main()
{
int x, y, z;
scanf("%d", &t);
for (int cas = 1; cas <= t; cas++) {
scanf("%d%d", &n, &q);
build(1, n, 1);
while (q--) {
scanf("%d%d%d", &x, &y, &z);
update(x, y, z, 1, n, 1);
}
printf("Case %d: The total value of the hook is %I64d.\n", cas, querry(1, n, 1, n, 1));
}
}*/