0%

2026 杭电暑期多校 8-1002-会自动求和的序列

题目大意

会自动求和的序列

有两个长度为 nn 的序列 aabb

接下来依次经过 mm 天。每天开始时,对于所有 1in1\le i\le n,先执行 aiai+bia_i\leftarrow a_i+b_i,然后执行当天的一次操作。

操作共有以下两种:

  • 1 l r x:对于所有 lirl\le i\le r,执行 bibi+xb_i\leftarrow b_i+x

  • 2 l r:求当前的区间和 i=lrai\sum_{i=l}^{r}a_i2642^{64} 取模后的结果。

第一行包含一个整数 TT,表示测试用例的组数。

对于每组测试用例:

  • 第一行包含两个整数 n,mn,m,分别表示序列长度和天数;

  • 接下来 nn 行,第 ii 行包含两个整数 ai,bia_i,b_i,表示两个序列的初始值;

  • 接下来 mm 行,每行包含一次操作,格式为 1 l r x2 l r

对于 OJ 中唯一一组正式测试数据,保证:

  • T=104T=10^4

  • 2n5×1052\le n\le 5\times 10^5

  • 1m5×1051\le m\le 5\times 10^5

  • 1ai,bi1091\le a_i,b_i\le 10^9

  • 1l<rn1\le l<r\le n

  • 1x1091\le x\le 10^9

  • n=106\sum n=10^6

  • m=106\sum m=10^6

对于每次第二类操作,输出一行一个整数,表示询问结果对 2642^{64} 取模后的值。

结果应表示为 0026412^{64}-1 之间的十进制整数。

输入

1
2
3
4
5
6
7
8
9
10
1
4 4
1 2
2 1
1 1
2 2
2 1 4
1 1 2 1
2 1 3
2 2 4

输出

1
2
3
12
18
23

初始时 a=[1,2,1,2]a=[1,2,1,2]b=[2,1,1,2]b=[2,1,1,2]

  • 11 :先令 aiai+bia_i\leftarrow a_i+b_i,得到 a=[3,3,2,4]a=[3,3,2,4]。操作为 2 1 4,输出 3+3+2+4=123+3+2+4=12

  • 22 :先令 aiai+bia_i\leftarrow a_i+b_i,得到 a=[5,4,3,6]a=[5,4,3,6]。操作为 1 1 2 1,将 b1,b2b_1,b_2 各加 11,得到 b=[3,2,1,2]b=[3,2,1,2],无输出。

  • 33 :先令 aiai+bia_i\leftarrow a_i+b_i,得到 a=[8,6,4,8]a=[8,6,4,8]。操作为 2 1 3,输出 8+6+4=188+6+4=18

  • 44 :先令 aiai+bia_i\leftarrow a_i+b_i,得到 a=[11,8,5,10]a=[11,8,5,10]。操作为 2 2 4,输出 8+5+10=238+5+10=23

思路讲解

image

其实只需要维护2个线段树,一个维护这个 xx 的和,一个维护一下 x×px \times p 的和就可以了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
rep(i, 1, m)
{
int op, l, r;
cin >> op >> l >> r;
if (op == 1)
{
ull x;
cin >> x;
treeX.rangeAdd(l, r, x);
treeXP.rangeAdd(l, r, x * i);
}
else
{
ull base = (sa[r] - sa[l - 1]) + (sb[r] - sb[l - 1]) * i;
// 这个就是上面公式中的 x*t,这个就是上面公式中的 x*p
ull update = treeX.query(l, r) * i - treeXP.query(l, r);
cout << base + update << '\n';
}
}

AC代码

心路历程(WA,TLE,MLE……)