Codeforces #442 Div2 F
#442 Div2 F
题意
给出一些包含两种类型(a, b)问题的问题册,每本问题册有一些题目,每次查询某一区间,问有多少子区间中 a 问题的数量等于 b 问题的数量加 \(k\) 。
分析
令包含 a 问题的问题册的问题数取正值,包含 b 问题的问题册的问题数取负值,那么问题就是求有多少子区间的和为 \(k\) 。
先求前缀和,记录 \(i\) 出现的次数 \(cnt[i]\)。当计算完前缀和 \(b[i-1]\) 后,考虑前缀和 \(b[i]\) ,\(cnt[b[i]-k]\)为对答案的贡献。
对于这种多个区间的询问,且区间从 \([L,R]\) 到 \([L,R+1]\) 或 \([L-1,R]\) 只需要 \(O(1)\) 的复杂度时,可以用莫队算法去优化,离线 + 分块。
注意,并不能直接用数组去存 \(cnt\) ,用 \(map\) 也会超时,这里可以离散化掉所有可能的值,因为我们只关心某种数字出现的次数。
code
#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
const int MAXN = 1e5 + 10;
const int BLOCK = 300;
int n, k;
ll a[MAXN], b[MAXN];
ll s[MAXN << 2];
int x[MAXN], y[MAXN], z[MAXN];
ll O[MAXN << 2];
struct P {
int l, r, b, i;
bool operator < (const P& o) const {
if(b != o.b) return b < o.b;
return r < o.r;
}
}p[MAXN];
ll ans[MAXN];
int main() {
scanf("%d%d", &n, &k);
for(int i = 0; i < n; i++) {
scanf("%lld", &a[i]);
if(a[i] != 1) a[i] = -1;
}
for(int i = 0; i < n; i++) {
scanf("%lld", &b[i]);
if(!i) b[i] = a[i] * b[i];
else b[i] = b[i - 1] + a[i] * b[i];
}
int c = 0;
b[n] = 0;
for(int i = 0; i <= n; i++) {
s[c++] = b[i];
s[c++] = b[i] + k;
s[c++] = b[i] - k;
}
sort(s, s + c);
int cc = unique(s, s + c) - s;
for(int i = 0; i <= n; i++) {
x[i] = lower_bound(s, s + cc, b[i] - k) - s;
y[i] = lower_bound(s, s + cc, b[i]) - s;
z[i] = lower_bound(s, s + cc, b[i] + k) - s;
}
int q;
scanf("%d", &q);
for(int i = 0; i < q; i++) {
scanf("%d%d", &p[i].l, &p[i].r);
p[i].l--;
p[i].r--;
p[i].b = p[i].l / BLOCK;
p[i].i = i;
}
sort(p, p + q);
int L = 0, R = 0;
ll res = 0;
for(int i = 0; i < q; i++) {
int l = p[i].l, r = p[i].r;
if(!i) {
if(l == 0) O[y[n]]++;
else O[y[l - 1]]++;
for(int j = l; j <= r; j++) {
res += O[x[j]];
O[y[j]]++;
}
} else {
for(int j = R + 1; j <= r; j++) {
res += O[x[j]];
O[y[j]]++;
}
for(int j = L - 1; j >= l; j--) {
if(j == 0) { res += O[z[n]]; O[y[n]]++; }
else { res += O[z[j - 1]]; O[y[j - 1]]++; }
}
for(int j = R; j > r; j--) {
O[y[j]]--;
res -= O[x[j]];
}
for(int j = L; j < l; j++) {
if(j == 0) { O[y[n]]--; res -= O[z[n]]; }
else { O[y[j - 1]]--; res -= O[z[j - 1]]; }
}
}
L = l;
R = r;
ans[p[i].i] = res;
}
for(int i = 0; i < q; i++) printf("%lld\n", ans[i]);
return 0;
}
Codeforces #442 Div2 F的更多相关文章
- Codeforces #541 (Div2) - F. Asya And Kittens(并查集+链表)
Problem Codeforces #541 (Div2) - F. Asya And Kittens Time Limit: 2000 mSec Problem Description Inp ...
- 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, ...
- Codeforces #451 Div2 F
#451 Div2 F 题意 给出一个由数字组成的字符串,要求添加一个加号和等号,满足数字无前导 0 且等式成立. 分析 对于这种只有数字的字符串,可以快速计算某一区间的字符串变成数字后并取模的值,首 ...
- Codeforces #452 Div2 F
#452 Div2 F 题意 给出一个字符串, m 次操作,每次删除区间 \([l,r]\) 之间的字符 \(c\) ,输出最后得到的字符串. 分析 通过树状数组和二分,我们可以把给定的区间对应到在起 ...
- Codeforces #442 Div2 E
#442 Div2 E 题意 给你一棵树,每个结点有开关(0表示关闭,1表示开启),两种操作: 反转一棵子树所有开关 询问一棵子树有多少开关是开着的 分析 先 DFS 把树上的结点映射到区间上,然后就 ...
- Codeforces #528 Div2 F (1087F) Rock-Paper-Scissors Champion 树状数组+set
题意:n个人站成一排,初始时刻每个人手中都有一个图案,可能是石头,剪刀,布3个中的1种,之后会随机选取相邻的两个人玩石头剪刀布的游戏,输的人会离开(如果两个人图案相同,则随机选择一个人离开).执行(n ...
- Codeforces #548 (Div2) - D.Steps to One(概率dp+数论)
Problem Codeforces #548 (Div2) - D.Steps to One Time Limit: 2000 mSec Problem Description Input Th ...
- Codeforces #180 div2 C Parity Game
// Codeforces #180 div2 C Parity Game // // 这个问题的意思被摄物体没有解释 // // 这个主题是如此的狠一点(对我来说,),不多说了这 // // 解决问 ...
- Codeforces #541 (Div2) - E. String Multiplication(动态规划)
Problem Codeforces #541 (Div2) - E. String Multiplication Time Limit: 2000 mSec Problem Descriptio ...
随机推荐
- [Leetcode] Reverse nodes in k group 每k个一组反转链表
Given a linked list, reverse the nodes of a linked list k at a time and return its modified list. If ...
- 【CF MEMSQL 3.0 B. Lazy Security Guard】
time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standa ...
- HDU3829:Cat VS Dog(最大独立集)
Cat VS Dog Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 125536/65536 K (Java/Others)Total ...
- ZOJ3261:Connections in Galaxy War(逆向并查集)
Connections in Galaxy War Time Limit: 3 Seconds Memory Limit: 32768 KB 题目链接:http://acm.zju.edu. ...
- hdu 3473 (划分树)2
Minimum Sum Time Limit: 16000/8000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Tota ...
- 使用HTML实现对汉字拼音的支持
<!DOCTYPE HTML><html> <head> <meta charset="utf-8"> <title>无 ...
- Redis(1) 初识Redis
redis介绍: Redis是一个开源(BSD许可)的内存数据结构存储,用作数据库,缓存和消息代理.它支持数据结构,如字符串(String),哈希(Hash),列表(List),集合(Set),具有范 ...
- javascript中arguments的应用——不定项传参求和
<script type="text/javascript"> window.onload=function(){ function sum(){ var result ...
- 记另类Request method 'GET' not supported
一般遇到Request method 'GET' not supported这种问题,大家都会找相应controller下的具体方法,把get改为post之类.但是我这次是在访问静态资源,static ...
- 从一段字符串中去除数字的shell方法