0%

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

题目大意

会自动求和的序列

有两个长度为 nn 的序列 aa 和 bb。

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

操作共有以下两种:

  • 1 l r x:对于所有 l≤i≤rl\le i\le r,执行 bi←bi+xb_i\leftarrow b_i+x。

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

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

对于每组测试用例:

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

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

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

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

  • T=104T=10^4;

  • 2≤n≤5×1052\le n\le 5\times 10^5;

  • 1≤m≤5×1051\le m\le 5\times 10^5;

  • 1≤ai,bi≤1091\le a_i,b_i\le 10^9;

  • 1≤l<r≤n1\le l<r\le n;

  • 1≤x≤1091\le x\le 10^9;

  • ∑n=106\sum n=10^6;

  • ∑m=106\sum m=10^6。

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

结果应表示为 00 到 264−12^{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 天:先令 ai←ai+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 天:先令 ai←ai+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 天:先令 ai←ai+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 天:先令 ai←ai+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……)