题目
输入输出样例
输入样例一
5 2
1 5 2 10
2 4 1 1
输出样例一
3 10
输入样例二
6 2
1 5 2 10
2 4 1 1
输出样例二
3 10
题解
- 设 a [ ] a[\ \ ] a[ ]为原数组, b [ ] b[\ \ ] b[ ]为 a [ ] a[\ \ ] a[ ]的差分数组, c [ ] c[\ \ ] c[ ]为 b [ ] b[\ \ ] b[ ]的差分数组
- 对于 l , r , s , t l,r,s,t l,r,s,t我们可以算出公差为 d = t − s r − l d=\frac{t-s}{r-l} d=r−lt−s
- 那么 a [ ] a[\ \ ] a[ ]数组中数字的改变为 a [ i ] = a [ i ] + s + d ∗ ( i − l ) ( l ≤ i ≤ r ) a[i]=a[i]+s+d*(i-l) \ \ \ \ \ (l \leq i \leq r) a[i]=a[i]+s+d∗(i−l) (l≤i≤r)
-
b
[
]
b[\ \ ]
b[ ]数组中数字(
b
[
i
]
=
a
[
i
]
−
a
[
i
−
1
]
b[i]=a[i]-a[i-1]
b[i]=a[i]−a[i−1])的改变为
b [ l ] = a [ l ] + s − a [ l − 1 ] = b [ l ] + s b[l]=a[l]+s-a[l-1]=b[l]+s b[l]=a[l]+s−a[l−1]=b[l]+s
b [ i ] = a [ i ] + d ∗ ( i − l ) − a [ i − 1 ] − d ∗ ( i − 1 − l ) = b [ i ] + d ( l + 1 ≤ i ≤ r ) b[i]=a[i]+d*(i-l)-a[i-1]-d*(i-1-l) = b[i]+d \ \ \ \ \ \ (l+1\leq i \leq r) b[i]=a[i]+d∗(i−l)−a[i−1]−d∗(i−1−l)=b[i]+d (l+1≤i≤r)
b [ r + 1 ] = a [ r + 1 ] − ( a [ r ] + t ) = b [ r + 1 ] − t b[r+1]=a[r+1]-(a[r]+t)=b[r+1]-t b[r+1]=a[r+1]−(a[r]+t)=b[r+1]−t -
c
[
]
c[\ \ ]
c[ ]数组中数字(
c
[
i
]
=
b
[
i
]
−
b
[
i
−
1
]
c[i]=b[i]-b[i-1]
c[i]=b[i]−b[i−1])的改变为
c [ l ] = b [ l ] + s − b [ l − 1 ] = c [ l ] + s c[l]=b[l]+s-b[l-1]=c[l]+s c[l]=b[l]+s−b[l−1]=c[l]+s
c [ l + 1 ] = b [ l + 1 ] + d − ( b [ l ] + s ) = c [ l + 1 ] + d − s c[l+1]=b[l+1]+d-(b[l]+s) = c[l+1]+d-s c[l+1]=b[l+1]+d−(b[l]+s)=c[l+1]+d−s
c [ i ] = ( b [ i ] + d ) − ( b [ i − 1 ] + d ) = c [ i ] ( l + 2 ≤ i ≤ r ) c[i]=(b[i]+d)-(b[i-1]+d)=c[i] \ \ \ \ \ \ \ (l+2\leq i \leq r) c[i]=(b[i]+d)−(b[i−1]+d)=c[i] (l+2≤i≤r)
c [ r + 1 ] = ( b [ r + 1 ] − t ) − ( b [ r ] + d ) = c [ r + 1 ] − t − d c[r+1]=(b[r+1]-t)-(b[r]+d)=c[r+1]-t-d c[r+1]=(b[r+1]−t)−(b[r]+d)=c[r+1]−t−d
c [ r + 2 ] = b [ r + 2 ] − ( b [ r + 1 ] − t ) = c [ r + 2 ] + t c[r+2]=b[r+2]-(b[r+1]-t)=c[r+2]+t c[r+2]=b[r+2]−(b[r+1]−t)=c[r+2]+t - 统计时求两遍前缀和即可
code
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 1e7 + 100;
template <typename T>
inline void read(T &s) {
s = 0;
T w = 1, ch = getchar();
while (!isdigit(ch)) { if (ch == '-') w = -1; ch = getchar(); }
while (isdigit(ch)) { s = (s<<1) + (s<<3) + (ch^48); ch = getchar(); }
s *= w;
}
int n, m;
LL a[maxn];
int main() {
read(n), read(m);
for (int i = 1; i <= m; ++i) {
LL l, r, s, t;
read(l), read(r), read(s), read(t);
LL d = (t-s) / (r-l); // 公差
a[l] += + s;
a[l+1] += d - s;
a[r+1] -= d + t;
a[r+2] += t;
}
LL sum1 = 0ll, sum2 = 0ll, ans = 0ll, Max = 0ll;
for (int i = 1; i <= n; ++i) {
sum1 += a[i];
sum2 += sum1;
Max = max(Max, sum2);
ans ^= sum2;
}
printf("%lld %lld\n", ans, Max);
return 0;
}