Can you let me have some f|

SilverLi

园龄:1年10个月粉丝:2关注:0

[CF877F] Ann and Books

Ann and Books の 传送门

si=j=1iaj[tj=1],ti=j=1iaj[tj=2]

满足条件的区间可以表示为 [l,r],满足 srsl1>trtl1+k

移一移项,srtr>sl1tl1+k

vali=siti,化简为 valr>vall1+k

然后用莫队就做完了

具体一点,存下当前区间所有的 vali

  1. 在右侧插入,答案加上 valnowk 的出现次数,再特判它本身

  2. 在左侧插入,答案加上 valnow+k 的出现次数,再特判它本身

删除就是把插入的代码倒着写一遍。

#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 中国大陆许可协议进行许可。

posted @   SilverLi  阅读(4)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起