[CF877F] Ann and Books
满足条件的区间可以表示为
移一移项,
令
然后用莫队就做完了。
具体一点,存下当前区间所有的
-
在右侧插入,答案加上
的出现次数,再特判它本身。 -
在左侧插入,答案加上
的出现次数,再特判它本身。
删除就是把插入的代码倒着写一遍。
#include <bits/stdc++.h> #include <bits/extc++.h> #define int long long using namespace std; inline int read() { int f = 0, ans = 0; char c = getchar(); while (!isdigit(c)) f |= c == '-', c = getchar(); while (isdigit(c)) ans = (ans << 3) + (ans << 1) + c - 48, c = getchar(); return f ? -ans : ans; } void write(int x) { if (x < 0) putchar('-'), x = -x; if (x > 9) write(x / 10); putchar(x % 10 + '0'); } const int N = 2e5 + 5, M = N * 3; int n, k, m, t[N], a[N]; int cnt, s1[N], s2[N], val[N]; int sq, mp[M], b[M], id[N][3]; int ans, res[N]; struct que { int l, r, id; bool operator<(const que &x) const { if (l / sq != x.l / sq) return l < x.l; return l / sq & 1 ? r < x.r : r > x.r; } } q[N]; inline int get(int x) { return lower_bound(b + 1, b + cnt + 1, x) - b; } inline void ins_l(int i) { ++mp[id[i][0]], ans += mp[id[i - 1][2]]; } inline void ins_r(int i, int l) { ans += mp[id[i][1]] + (val[i] == val[l - 1] + k), ++mp[id[i][0]]; } inline void del_l(int i) { ans -= mp[id[i - 1][2]], --mp[id[i][0]]; } inline void del_r(int i, int l) { --mp[id[i][0]], ans -= mp[id[i][1]] + (val[i] == val[l - 1] + k); } signed main() { // freopen(".in", "r", stdin); // freopen(".out", "w", stdout); n = read(), k = read(); sq = sqrt(n); for (int i = 1; i <= n; ++i) t[i] = read(); b[++cnt] = val[0]; b[++cnt] = val[0] - k; b[++cnt] = val[0] + k; for (int i = 1; i <= n; ++i) { a[i] = read(); s1[i] = s1[i - 1] + a[i] * (t[i] == 1); s2[i] = s2[i - 1] + a[i] * (t[i] == 2); val[i] = s1[i] - s2[i]; b[++cnt] = val[i]; b[++cnt] = val[i] - k; b[++cnt] = val[i] + k; } sort(b + 1, b + cnt + 1); cnt = unique(b + 1, b + cnt + 1) - b - 1; for (int i = 0; i <= n; ++i) id[i][0] = get(val[i]), id[i][1] = get(val[i] - k), id[i][2] = get(val[i] + k); m = read(); for (int i = 1; i <= m; ++i) q[i].l = read(), q[i].r = read(), q[i].id = i; sort(q + 1, q + m + 1); int l = 1, r = 0; for (int i = 1; i <= m; ++i) { while (l > q[i].l) ins_l(--l); while (r < q[i].r) ins_r(++r, l); while (l < q[i].l) del_l(l++); while (r > q[i].r) del_r(r--, l); res[q[i].id] = ans; } for (int i = 1; i <= m; ++i) write(res[i]), putchar('\n'); return 0; }
本文作者:SilverLi
本文链接:https://www.cnblogs.com/Silver-Wolf/p/18701810/CF877F
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】