[CF877F] Ann and Books
\(s_i=\sum_{j=1}^i a_j \left [ t_j=1 \right ], t_i=\sum_{j=1}^i a_j \left [ t_j=2 \right ]\)。
满足条件的区间可以表示为 \(\left [ l, r \right ]\),满足 \(s_r-s_{l-1}>t_r-t_{l-1}+k\)。
移一移项,\(s_r-t_r>s_{l-1}-t_{l-1}+k\)。
令 \(val_i=s_i-t_i\),化简为 \(val_r>val_{l-1}+k\)。
然后用莫队就做完了。
具体一点,存下当前区间所有的 \(val_i\)。
-
在右侧插入,答案加上 \(val_{now}-k\) 的出现次数,再特判它本身。
-
在左侧插入,答案加上 \(val_{now}+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;
}

浙公网安备 33010602011771号