Luogu4231 三步必杀
跟前两天考试题挺像的,就直接说做法了
其实就是你发现在各种数据结构都不是很资瓷之后,你选择了差分
发现差分之后每次操作就变成了对差分序列做区间覆盖
可以 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; }
禁止诸如开发者知识库/布布扣/码迷/学步园/马开东等 copy 他人博文乃至博客的网站转载
,用户转载请注明出处:https://www.cnblogs.com/xcysblog/