题目链接

Description

给定一个长度为 \(N\) 的序列 \(a\),和一个区间 \([L, R]\)。

求多少连续子序列的权值和在区间内,即满足 \(1 \le i \le j \le n\) 且满足 \(L \le \sum_{k=i}^{j} a[i] \le R\) 的方案数。

Solution

区间和,很容易想到用前缀和转换,这样区间相关变成了两个点。设 \(s\) 为 \(a\) 的前缀和,那么统计就变成了这样。

统计 \(0 \le i < j \le n\) 中满足 \(L \le s[j] - s[i] \le R\) 的方案数的。数据只有一组询问,显然是支持我们枚举一维,的不妨枚举 \(s[i]\),那么转化一下式子,就是满足 \(L + s[i] \le s[j] \le R + s[i]\) 且 \(i < j\) 的 \(j\) 的数量。

这就是一个显然的二维偏序问题,做法就是:

  • 倒序枚举 \(i\)
  • 查询答案
  • 插入 \(s[i]\)

单调修改、区间查询这个操作我们再熟悉不过了。但是这次因为离散化会把值域信息搞没,所以不能离散化,只能动态开点线段树。(后来想了一下好像也可以,把数值全部打进数组离散化一下,所以写了两个版本)。

时间复杂度

\(O(n\log_2 10^{10})\)

Code

动态开点线段树版

#include <iostream>
#include <cstdio> using namespace std; typedef long long LL; const int N = 100005; int n, L, R, rt, idx; struct T{
int l, r, v;
} t[N * 30]; LL Lt = 9e18, Rt = -9e18; LL s[N], ans = 0; void inline pushup(int p) {
t[p].v = t[t[p].l].v + t[t[p].r].v;
} void insert(int &p, LL l, LL r, LL x) {
if (!p) p = ++idx;
t[p].v++;
if (l == r) return;
LL mid = (l + r) >> 1;
if (x <= mid) insert(t[p].l, l, mid, x);
else insert(t[p].r, mid + 1, r, x);
} int query(int p, LL l, LL r, LL x, LL y) {
if (!p) return 0;
if (x <= l && r <= y) return t[p].v;
LL mid = (l + r) >> 1, res = 0;
if (x <= mid) res += query(t[p].l, l, mid, x, y);
if (mid < y) res += query(t[p].r, mid + 1, r, x, y);
return res;
} int main() {
scanf("%d%d%d", &n, &L, &R);
for (int i = 1; i <= n; i++) scanf("%lld", &s[i]), s[i] += s[i - 1];
for (int i = 1; i <= n; i++) {
Lt = min(Lt, s[i]);
Rt = max(Rt, R + s[i]);
}
for (int i = n; ~i; i--) {
ans += query(rt, Lt, Rt, L + s[i], R + s[i]);
if (i) insert(rt, Lt, Rt, s[i]);
}
printf("%lld\n", ans);
return 0;
}

树状数组版

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std; typedef long long LL; const int N = 100005; int n, L, R, tot, c[N]; LL s[N], d[N], ans = 0; int inline get(LL x) {
return lower_bound(d + 1, d + 1 + tot, x) - d;
} void inline add(int x) {
for (; x <= tot; x += x & -x) c[x]++;
} int inline ask(int x) {
int res = 0;
for (; x; x -= x & -x) res += c[x];
return res;
} int main() {
scanf("%d%d%d", &n, &L, &R);
for (int i = 1; i <= n; i++)
scanf("%lld", &s[i]), s[i] += s[i - 1], d[++tot] = s[i];
sort(d + 1, d + 1 + tot);
tot = unique(d + 1, d + 1 + tot) - d - 1;
for (int i = n; ~i; i--) {
int A = lower_bound(d + 1, d + 1 + tot, L + s[i]) - d - 1;
int B = upper_bound(d + 1, d + 1 + tot, R + s[i]) - d - 1;
ans += ask(B) - ask(A);
if (i) add(get(s[i]));
}
printf("%lld\n", ans);
return 0;
}

BJOI2016 回转寿司的更多相关文章

  1. P5459 [BJOI2016]回转寿司

    传送门 暴力怎么搞,维护前缀和 $s[i]$ ,对于每一个 $s[i]$,枚举所有 $j\in[0,i-1]$,看看 $s[i]-s[j]$ 是否属于 $[L,R]$ 如果属于就加入答案 $s[i]- ...

  2. BZOJ_4627_[BeiJing2016]回转寿司_离散化+树状数组

    BZOJ_4627_[BeiJing2016]回转寿司_离散化+树状数组 Description 酷爱日料的小Z经常光顾学校东门外的回转寿司店.在这里,一盘盘寿司通过传送带依次呈现在小Z眼前.不同的寿 ...

  3. bzoj 4627: [BeiJing2016]回转寿司 -- 权值线段树

    4627: [BeiJing2016]回转寿司 Time Limit: 10 Sec  Memory Limit: 256 MB Description 酷爱日料的小Z经常光顾学校东门外的回转寿司店. ...

  4. bzoj 4627: [BeiJing2016]回转寿司

    4627: [BeiJing2016]回转寿司 Description 酷爱日料的小Z经常光顾学校东门外的回转寿司店.在这里,一盘盘寿司通过传送带依次呈现在小Z眼前.不同的寿 司带给小Z的味觉感受是不 ...

  5. 【BZOJ4627】[BeiJing2016]回转寿司 SBT

    [BZOJ4627][BeiJing2016]回转寿司 Description 酷爱日料的小Z经常光顾学校东门外的回转寿司店.在这里,一盘盘寿司通过传送带依次呈现在小Z眼前.不同的寿司带给小Z的味觉感 ...

  6. [LOJ2736] [JOISC 2016 Day 3] 回转寿司 (分块+堆)

    [LOJ2736] [JOISC 2016 Day 3] 回转寿司 (分块+堆) 题面 给出一个有n 个点的环,环上各点有一个初始权值 \(a_i\) 给出 Q 个询问,每次询问给出一个区间 [l,r ...

  7. K - 回转寿司(值域段数(板题) + 动态开点)

    回转寿司 Description 酷爱日料的小Z经常光顾学校东门外的回转寿司店.在这里,一盘盘寿司通过传送带依次呈现在小Z眼前.不同的寿 司带给小Z的味觉感受是不一样的,我们定义小Z对每盘寿司都有一个 ...

  8. 【bzoj4627】[BeiJing2016]回转寿司 离散化+树状数组

    题目描述 给出一个长度为n的序列,求所有元素的和在[L,R]范围内的连续子序列的个数. 输入 第一行包含三个整数N,L和R,分别表示寿司盘数,满意度的下限和上限. 第二行包含N个整数Ai,表示小Z对寿 ...

  9. bzoj4627: [BeiJing2016]回转寿司

    权值线段树. 要求 L<=(s[i]-s[j])<=R  (i<j). 的i和j的数量. 所以把前缀和s加入一棵权值线段树,每次询问满足条件的范围中的权值的个数. 权值线段树不能像普 ...

随机推荐

  1. nginx&http 第三章 ngx http ngx_http_process_request_headers

    HTTP 请求行正确处理完成后,针对 HTTP/1.0 及以上版本紧接着要做的就是请求 HEADER 的处理与解析了 /** * 用于处理http的header数据 * 请求头: * Host: lo ...

  2. 极客mysql01

    1.MySQL的框架有几个组件, 各是什么作用?连接器:负责跟客户端建立连接.获取权限.维持和管理连接.查询缓存:查询请求先访问缓存(key 是查询的语句,value 是查询的结果).命中直接返回.不 ...

  3. Linux文件监控工具——inotify-tools

    举例: ip.txt内容如下: 10.1.1.11 root 123 10.1.1.22 root 111 10.1.1.33 root 123456 10.1.1.44 root 54321 写法1 ...

  4. 面试大厂必看!就凭借这份Java多线程和并发面试题,我拿到了字节和美团的offer!

    最近好多粉丝私信我说在最近的面试中老是被问到多线程和高并发的问题,又对这一块不是很了解,很简单就被面试官给问倒了,被问倒的后果当然就是被刷下去了,因为粉丝要求,我最近也是花了两天时间 给大家整理了这一 ...

  5. 分布式监控系统之Zabbix 使用SNMP、JMX信道采集数据

    前文我们了解了zabbix的被动.主动以及web监控相关话题,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/14024212.html:今天我们来了解下zabb ...

  6. 简单实用的Boom 3D进阶使用教程分享

    对于初学者来说,简单体验Boom 3D的3D环绕音效,就可以通过普通耳机享受到高品质耳机的动人音效.而对于进阶者来说,Boom 3D灵活的预设功能,能让其享受到自由调整均衡器.低音的乐趣. 图1:Bo ...

  7. cocoslua3.17 android机器上播放音效不全

    开发过程中遇到一个问题,一个8秒的音效,在android机器上播放不完就结束了:网上说是由于android播放音效的内存限制的:原因知道了,那怎么解决呢? 通过各种搜索查找发现还是解决不了问题,然后自 ...

  8. python基础之条件语句

    检查相等和不等 多个检查条件 age1 = 22 age2 = 19 s1 = age1 > 21 and age2 > 19 print(s1) s2 = age1 > 21 or ...

  9. Hibernate的配置跟简单创建一个表并插入一条数据

    首先官网下载一个hibernate的架包,由于时间关系,博主已经分享到了百度网盘:https://pan.baidu.com/s/1Mw0Og3EKnouf84Njz9UicQ,提取码lens Hib ...

  10. 深度阅读:大学生课外知识补充,这些课堂上不教的 C++ 的基本特性你都知道吗?

    来源:知乎 王师傅的专栏 C++ 作为一个历史久远,功能丰(yong)富(zhong)而且标准与时俱进的语言,理应什么都能做,什么都用得起来.不过日常使用中我们初学者真的好像只学到了其中的一部分,对于 ...