[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号
浙公网安备 33010602011771号