P12489 [集训队互测 2024] 线段树与区间加
题目描述
普罗在图书馆找到了一本关于算法的书。书中介绍了一种名为“线段树”的数据结构。
>
>线段树是一种有根的二叉树,其每个节点对应了序列上的一个区间 $[l,r]$,其中根节点对应 $[1,n]$。
>
>对于每个节点,若其代表的序列区间 $[l,r]$ 满足 $l=r$,则其为叶节点;否则存在整数 $k(l\le k
>线段树可以实现单点修改,区间修改,区间查询等操作。其中区间修改操作的实现通常需要维护名为懒惰标记的额外信息。
>
在简单了解了线段树如何维护区间加之后,普罗想要实现一个维护区间加的线段树。于是他写下了如下的代码:
```cpp
#define len(i) (r[i]-l[i]+1)
void push_down(int i)
{
a[lc[i]]+=len(lc[i])*lz[i];
lz[lc[i]]+=lz[i];
a[rc[i]]+=len(rc[i])*lz[i];
lz[rc[i]]+=lz[i];
lz[i]=0;
return;
}
void add(int i,int ql,int qr,unsigned k)
{
if(qr
输入格式
第一行两个整数 $n,m$,表示线段树维护的序列长度和操作次数。
接下来 $2n-1$ 行,第 $i$ 行首先是四个整数 $l_i,r_i,va_i,vb_i$,表示线段树上第 $i$ 个节点对应的区间的左端点和右端点,以及节点上的两个额外权值。如果这个节点不是根节点,那么接下来还有两个整数 $lc_i,rc_i$,表示这个节点的左儿子编号和右儿子编号。
接下来 $m$ 行,每行三个整数 $ql_i,qr_i,k_i$,表示一次区间加操作的左端点,右端点和增加的值。
输出格式
在每次区间加操作后输出一行一个正整数表示 `foobar` 函数的返回值。
说明/提示
【数据规模与约定】
| 测试点编号 | $n,q$ | 其他约定 |
| :-----------: | :-----------: | :-----------: |
| $1\sim5$ | $\le2000$ | 无 |
| $6\sim10$ | $\le40000$ | 无 |
| $11\sim15$ | $\le2\times10^5$ | 保证存在一个线段树上的节点对应的区间为 $[ql,qr]$ |
| $16\sim20$ | $\le2\times10^5$ | 保证不同的 $ql,qr$ 不超过 $200$ 种 |
| $21\sim25$ | $\le2\times10^5$ | 无 |
如果测试点编号 $\bmod 5$ 为 $2$ 或 $3$,该测试点保证 $va_i=0$。
如果测试点编号 $\bmod 5$ 为 $4$ 或 $0$,该测试点保证 $vb_i=0$。
对于 $100\%$ 的数据,保证 $1\le n,q\le2\times10^5$,给出的线段树和区间加操作是合法的,$0\le va_i,vb_i,k_i