跟前两天考试题挺像的,就直接说做法了
其实就是你发现在各种数据结构都不是很资瓷之后,你选择了差分
发现差分之后每次操作就变成了对差分序列做区间覆盖
可以 log 做,但显然 mlogn 在 0.5s 之内是会非常爆炸的
可能因为上边想到想到差分序列的性质之后太兴奋了
实际上标准的区间加也是可以差分的啊!
这样再差分一次就可以做到 O(1) 修改了
由于询问是最后的所以只要最后 O(n) 的求两边前缀和就好了
代码:
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <cstdio>
using namespace std;
typedef long long ll;
const int MAX_N = 10000005;
int n, m;
int pls[MAX_N];
inline int rd() {
register int x = 0, c = getchar();
register bool f = false;
while (!isdigit(c)) {
f = (c == '-');
c = getchar();
}
while (isdigit(c)) {
x = x * 10 + (c ^ 48);
c = getchar();
}
return f ? -x : x;
}
inline ll rd_ll() {
register ll x = 0;
register int c = getchar();
register bool f = false;
while (!isdigit(c)) {
f = (c == '-');
c = getchar();
}
while (isdigit(c)) {
x = x * 10 + (c ^ 48);
c = getchar();
}
return f ? -x : x;
}
int main() {
n = rd(); m = rd();
register int l, r;
register ll s, e, d;
for (int i = 1; i <= m; ++i) {
l = rd(); r = rd(); s = rd_ll(); e = rd_ll();
d = (e - s) / (r - l);
pls[l] += s;
pls[l + 1] -= s - d;
pls[r + 1] -= e + d;
pls[r + 2] += e;
}
register ll d0 = 0, d1 = 0, xor_sig = 0, max_val = 0;
for (int i = 1; i <= n; ++i) {
d0 += (d1 += pls[i]);
xor_sig ^= d0;
max_val = max(max_val, d0);
}
printf("%lld %lld\n", xor_sig, max_val);
return 0;
}