题意
对一个数组的某个区间加上一段等差数列,求出若干个操作后每个元素的值。
思路
考虑差分。
设
A
A
A为原数组,
B
B
B为一阶差分数组,
C
C
C为二阶差分数组。
对
[
l
,
r
]
[l,r]
[l,r]加上首项为
s
s
s,末项为
e
e
e,公差为
d
d
d的等差数列,可得
A
i
=
A
i
+
s
+
(
i
−
l
)
∗
d
A_i=A_i+s+(i-l)*d
Ai=Ai+s+(i−l)∗d
B
l
=
(
A
l
+
s
)
−
A
l
−
1
=
B
l
+
s
B_l=(A_l+s)-A_{l-1}=B_l+s
Bl=(Al+s)−Al−1=Bl+s
B
i
=
(
A
i
+
s
∗
(
i
−
l
)
∗
d
)
−
(
A
i
−
1
+
s
∗
(
i
−
1
−
l
)
∗
d
)
=
B
i
+
d
B_i=(A_i+s*(i-l)*d)-(A_{i-1}+s*(i-1-l)*d)=B_i+d
Bi=(Ai+s∗(i−l)∗d)−(Ai−1+s∗(i−1−l)∗d)=Bi+d
B
r
+
1
=
A
r
+
1
−
(
A
r
+
e
)
=
B
r
+
1
−
e
B_{r+1}=A_{r+1}-(A_r+e)=B_{r+1}-e
Br+1=Ar+1−(Ar+e)=Br+1−e
C
l
=
(
B
l
+
s
)
−
(
B
l
−
1
)
=
C
l
+
s
C_l=(B_l+s)-(B_{l-1})=C_l+s
Cl=(Bl+s)−(Bl−1)=Cl+s
C
l
+
1
=
(
B
l
+
1
+
d
)
−
(
B
l
+
s
)
=
C
l
+
d
−
s
C_{l+1}=(B_{l+1}+d)-(B_l+s)=C_l+d-s
Cl+1=(Bl+1+d)−(Bl+s)=Cl+d−s
C
r
+
1
=
(
B
r
+
1
−
e
)
−
(
B
r
+
d
)
=
C
l
−
d
−
e
C_{r+1}=(B_{r+1}-e)-(B_r+d)=C_l-d-e
Cr+1=(Br+1−e)−(Br+d)=Cl−d−e
C
r
+
2
=
B
r
+
2
−
(
B
r
+
1
−
e
)
=
C
r
+
2
+
e
C_{r+2}=B_{r+2}-(B_{r+1}-e)=C_{r+2}+e
Cr+2=Br+2−(Br+1−e)=Cr+2+e
故只用修改4个值,做两次前缀和即可。
代码
#include <cstdio>
#include <algorithm>
#define int long long
const int N = 1e7 + 5;
int n, m, ans1, ans2;
int a[N];
signed main() {
scanf("%lld %lld", &n, &m);
for (int i = 1, l, r, s, e; i <= m; i++) {
scanf("%lld %lld %lld %lld", &l, &r, &s, &e);
int d = (e - s) / (r - l);
a[l] += s;
a[l + 1] += d - s;
a[r + 1] -= d + e;
a[r + 2] += e;
}
for (int i = 1; i <= n; i++)
a[i] += a[i - 1];
for (int i = 1; i <= n; i++)
a[i] += a[i - 1], ans1 ^= a[i], ans2 = std::max(ans2, a[i]);
printf("%lld %lld", ans1, ans2);
}