#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的更多相关文章

  1. Codeforces #541 (Div2) - F. Asya And Kittens(并查集+链表)

    Problem   Codeforces #541 (Div2) - F. Asya And Kittens Time Limit: 2000 mSec Problem Description Inp ...

  2. 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, ...

  3. Codeforces #451 Div2 F

    #451 Div2 F 题意 给出一个由数字组成的字符串,要求添加一个加号和等号,满足数字无前导 0 且等式成立. 分析 对于这种只有数字的字符串,可以快速计算某一区间的字符串变成数字后并取模的值,首 ...

  4. Codeforces #452 Div2 F

    #452 Div2 F 题意 给出一个字符串, m 次操作,每次删除区间 \([l,r]\) 之间的字符 \(c\) ,输出最后得到的字符串. 分析 通过树状数组和二分,我们可以把给定的区间对应到在起 ...

  5. Codeforces #442 Div2 E

    #442 Div2 E 题意 给你一棵树,每个结点有开关(0表示关闭,1表示开启),两种操作: 反转一棵子树所有开关 询问一棵子树有多少开关是开着的 分析 先 DFS 把树上的结点映射到区间上,然后就 ...

  6. Codeforces #528 Div2 F (1087F) Rock-Paper-Scissors Champion 树状数组+set

    题意:n个人站成一排,初始时刻每个人手中都有一个图案,可能是石头,剪刀,布3个中的1种,之后会随机选取相邻的两个人玩石头剪刀布的游戏,输的人会离开(如果两个人图案相同,则随机选择一个人离开).执行(n ...

  7. Codeforces #548 (Div2) - D.Steps to One(概率dp+数论)

    Problem   Codeforces #548 (Div2) - D.Steps to One Time Limit: 2000 mSec Problem Description Input Th ...

  8. Codeforces #180 div2 C Parity Game

    // Codeforces #180 div2 C Parity Game // // 这个问题的意思被摄物体没有解释 // // 这个主题是如此的狠一点(对我来说,),不多说了这 // // 解决问 ...

  9. Codeforces #541 (Div2) - E. String Multiplication(动态规划)

    Problem   Codeforces #541 (Div2) - E. String Multiplication Time Limit: 2000 mSec Problem Descriptio ...

随机推荐

  1. 2018-8-10考试 T3. 朝暮(akekure)

    题目大意:有$n$个点和$m$条边的图($n - 1 \leq m \leq n + 5$),每个点要么黑要么白,两个黑点不可以相邻,问方案数 题解:可以发现当图为一棵树的时候只需要一个树形$DP$ ...

  2. HTML5 Canvas圣诞树

    又逢圣诞了,为了让小站NowaMagic有点节日气氛,这里也弄一棵圣诞树放放-大家可以先看下效果. 效果演示 <canvas id="c"></canvas> ...

  3. Endnote 中文参考文献样式修改版

    http://blog.yuelong.info/post/endnote-gbt7714-2005.html 很多人不知道 EndNote 是自带中文参考文献引用样式的,即符合<文后参考文献著 ...

  4. Java super和this

    this this是自身的一个对象,代表对象本身,可以理解为:指向对象本身的一个指针. this的用法在java中大体可以分为3种: 1.普通的直接引用 这种就不用讲了,this相当于是指向当前对象本 ...

  5. 大数问题,通常用JAVA

    e.g. HDU1002 简单加法 import java.math.BigInteger; import java.util.Scanner; public class Main { public ...

  6. kafka+flume+HDFS日志采集项目框架

    1,项目图如下: 2, 实现过程 启动HDFS: sbin/start-dfs.sh 启动zookeeper(三台): bin/zkServer.sh start 启动kafka(三台): root@ ...

  7. AtCoder Regular Contest 082 F

    Problem Statement We have a sandglass consisting of two bulbs, bulb A and bulb B. These bulbs contai ...

  8. noip2014 提高组

    T1 生活大爆炸版 石头剪刀布 题目传送门 就是道模拟题咯 #include<algorithm> #include<cstdio> #include<cstring&g ...

  9. Linux XZ格式的解压

    xz这个压缩可能很多都很陌生,不过您可知道xz是绝大数linux默认就带的一个压缩工具. 之前xz使用一直很少,所以几乎没有什么提起. 我是在下载phpmyadmin的时候看到这种压缩格式的,phpm ...

  10. python configparse

    # 参考:https://www.cnblogs.com/lily1989/p/8401005.html # https://blog.csdn.net/willhuo/article/details ...