CF877F Ann and Books

题意:

商店里有 \(n\) 本书,每本书中有 \(a_i\) 个 \(t_i=1/2\) 类问题。

\(m\) 次询问,每次询问给出一个区间,求有多少个符合下列条件的区间:

  • 这个区间是给出区间的子区间
  • 这个区间的所有书中第 \(1\) 类问题比第 \(2\) 类问题多 \(k\) 个,其中 \(k\) 在所有询问中相同。

抽象一下,也就是求 \([L, R]\) 内有多少个子区间 \([l, r]\) 满足

\[\sum_l^r a[1][i] = \sum_l^r a[2][i] + k
\]

\[s[1][r] - s[1][l - 1] = s[2][r] - s[2][l - 1] + k
\]
\[s[1][r] - s[2][r] = s[1][l - 1] - s[2][l - 1] + k
\]

令 \(v[i] = s[1][i] - s[2][i]\),将原问题转化为 \([L - 1, R]\) 内多少对 \((i, j)\) 满足

  • \(i < j\)
  • \(v[i] + k = v[j]\)

用莫队维护。

如果在现有区间左侧加入一个数 \(x\),则 \(x\) 只能作为区间左端点,答案加上当前的 \(cnt[x + k]\),删除同理。

如果在现有区间右侧加入一个数 \(x\),则 \(x\) 只能作为区间右端点,答案加上当前的 \(cnt[x - k]\),删除同理。

如果 \(k = 0\),由于自己和自己不能产生贡献,需考虑更新答案和更新 \(cnt\) 的顺序。

离散化的时候注意把 \(v - k\) 和 \(v + k\) 也放进去。

#include<bits/stdc++.h>
#define rep(i, a, b) for(int i = (a); i <= (b); ++ i)
#define per(i, a, b) for(int i = (a); i >= (b); -- i)
#define pb emplace_back
#define All(X) X.begin(), X.end()
using namespace std;
using ll = long long;
constexpr int N = 1e5 + 5, B = 300; #define c(x) ((x) / B) struct Node {
int l, r, id;
bool operator < (const Node &x) {
if(c(l) != c(x.l)) return c(l) < c(x.l);
if(c(l) & 1) return c(r) < c(x.r);
return c(r) > c(x.r);
}
} q[N]; ll n, m, k, t[N], v[N], lv[N], rv[N], b[N * 3], cnt[N * 3], idx;
ll res, ans[N]; void add(int x, int y) {
res += cnt[y], ++ cnt[x]; // 先加上贡献,再更新数值,防止 x = y,del同理
} void del(int x, int y) {
-- cnt[x], res -= cnt[y];
} int main() {
ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
cin >> n >> k;
rep(i, 1, n) cin >> t[i];
rep(i, 1, n) {
cin >> v[i];
v[i] = v[i - 1] + (t[i] == 1 ? 1 : -1) * v[i];
}
rep(i, 0, n) {
b[++ idx] = v[i];
b[++ idx] = v[i] - k;
b[++ idx] = v[i] + k;
}
sort(b + 1, b + idx + 1);
int tot = unique(b + 1, b + idx + 1) - b - 1;
rep(i, 0, n) {
lv[i] = lower_bound(b + 1, b + tot + 1, v[i] - k) - b;
rv[i] = lower_bound(b + 1, b + tot + 1, v[i] + k) - b;
v[i] = lower_bound(b + 1, b + tot + 1, v[i]) - b;
}
cin >> m;
rep(i, 1, m) cin >> q[i].l >> q[i].r, q[i].id = i;
sort(q + 1, q + m + 1); int l = 0, r = -1;
rep(i, 1, m) {
auto[L, R, id] = q[i];
-- L;
while(l < L) del(v[l], rv[l]), ++ l;
while(l > L) -- l, add(v[l], rv[l]);
while(r < R) ++ r, add(v[r], lv[r]);
while(r > R) del(v[r], lv[r]), -- r;
ans[id] = res;
}
rep(i, 1, m) cout << ans[i] << '\n';
return 0;
}

CF877F Ann and Books (分类统计贡献+普通莫队)的更多相关文章

  1. [CF877F]Ann and Books

    题目大意: 有$n(n\le10^5)$个数$w_{1\sim n}(|w_i|\le10^9)$,并给定一个数$k(|k|\le10^9)$.$q(q\le10^5)$次询问,每次询问区间$[l,r ...

  2. [Codeforces86D]Powerful array(莫队算法)

    题意:定义K[x]为元素x在区间[l,r]内出现的次数,那么它的贡献为K[x]*K[x]*x 给定一个序列,以及一些区间询问,求每个区间的贡献 算是莫队算法膜版题,不带修改的 Code #includ ...

  3. cf 442 div2 F. Ann and Books(莫队算法)

    cf 442 div2 F. Ann and Books(莫队算法) 题意: \(给出n和k,和a_i,sum_i表示前i个数的和,有q个查询[l,r]\) 每次查询区间\([l,r]内有多少对(i, ...

  4. Codeforces 877F Ann and Books 莫队

    转换成前缀和, 预处理一下然后莫队. #include<bits/stdc++.h> #define LL long long #define fi first #define se se ...

  5. D. Powerful array 离线+莫队算法 给定n个数,m次查询;每次查询[l,r]的权值; 权值计算方法:区间某个数x的个数cnt,那么贡献为cnt*cnt*x; 所有贡献和即为该区间的值;

    D. Powerful array time limit per test seconds memory limit per test megabytes input standard input o ...

  6. Codeforces 617E XOR and Favorite Number(莫队算法)

    题目大概说给一个序列,多次询问区间异或和为k的连续子序列有多少个. 莫队算法,利用异或的性质,通过前缀和求区间和,先处理出序列各个前缀和,然后每次区间转移时维护i以及i-1前缀和为某数的个数并增加或减 ...

  7. uoj #58. 【WC2013】糖果公园(树上莫队算法+修改操作)

    [题目链接] http://uoj.ac/problem/58 [题意] 有一棵树,结点有自己的颜色,若干询问:u,v路径上的获益,并提供修改颜色的操作. 其中获益定义为Vc*W1+Vc*W2+…+V ...

  8. [bzoj4540][Hnoi2016][序列] (莫队算法+单调栈+st表)

    Description 给定长度为n的序列:a1,a2,…,an,记为a[1:n].类似地,a[l:r](1≤l≤r≤N)是指序列:al,al+1,…,ar-1,ar.若1≤l≤s≤t≤r≤n,则称a ...

  9. 【HNOI2016】序列 莫队+单调栈+RMQ

    Description 给定长度为n的序列:a1,a2,…,an,记为a[1:n].类似地,a[l:r](1≤l≤r≤N)是指序列:al,al+1,…,ar-1,ar.若1≤l≤s≤t≤r≤n,则称a ...

  10. BZOJ_3289_Mato的文件管理_莫队+树状数组

    BZOJ_3289_Mato的文件管理_莫队+树状数组 Description Mato同学从各路神犇以各种方式(你们懂的)收集了许多资料,这些资料一共有n份,每份有一个大小和一个编号 .为了防止他人 ...

随机推荐

  1. go语言漏桶算法思路简单实现

    package main import ( "fmt" "time" ) // 桶 type LeakBucket struct { capacity int ...

  2. 12 CSS 的float属性

    12 CSS 的float属性 流动布局 流动模型(Flow),即文档流,浏览器打开HTML网页时,从上往下,从左往右,逐一加载. 在正常情况下,HTML元素都会根据文档流来分布网页内容的. 文档流有 ...

  3. #特殊判断#牛客练习赛71 A 回文数

    题目 分析 首先出现奇数次的数超过1显然无解 并且只有多个0或者只有一个非0数字并且其它都是0也无解 然后由于没有前导0所以先要找到最小的非0数,先占据首尾 最后按照常规方法前一半从左到右依次递增 注 ...

  4. Jetty使用入门

    社区当前推荐开发者使用Jetty 12.X版本. 依据End of Community Support for Jetty 9.x - June 2022,社区对Jetty 9.x的支持,已在2022 ...

  5. np.squeeze()

    np.squeeze() 是 NumPy 库中的一个函数,用于从数组中删除单维度的条目.它返回一个在输入数组中删除了尺寸为 1 的维度的新数组. 下面是使用 np.squeeze() 的示例代码: 点 ...

  6. HarmonyOS—使用Web组件加载页面

      页面加载是Web组件的基本功能.根据页面加载数据来源可以分为三种常用场景,包括加载网络页面.加载本地页面.加载HTML格式的富文本数据. 页面加载过程中,若涉及网络资源获取,需要配置ohos.pe ...

  7. stack-c++

    #include <iostream> using namespace std; template <typename T> class Stack{ private: int ...

  8. Javascript中的继承?如何实现继承?

    一.是什么 继承(inheritance)是面向对象软件技术当中的一个概念 如果一个类别B"继承自"另一个类别A,就把这个B称为"A的子类",而把A称为&quo ...

  9. DM 传统行业SQL优化案例

    来OB这么久还没有接触啥金融的SQL,只能发点其他行业的数据库SQL优化案例. 今天拿到手的这个案例SQL 传统行业的,很奇葩的SQL,表设计三范式都没弄好. 什么医疗,交通,能源这些传统行业的业务设 ...

  10. uniapp小程序页面实现元素与胶囊进行居中对齐

    无论是否为uni,关键在于获取胶囊中点的位置,如果是原生小程序根据小程序文档获取,其余逻辑处理是一致的 代码语法都只是技术选择,重点是逻辑处理,对于技术的运用,代码技术好比是积木,好的程序就是好的组合 ...