[HNOI 2017]影魔
Description
给你一段长度为 \(n\) 的序列 \(K\) 。 \(m\) 组询问,每次给定左右端点 \(l,r\) 。求出满足区间内下述贡献和。
- 如果一个区间的两个端点是这一个区间的最大与次大值,那么将获得 \(p_1\) 的价值;
- 如果一个区间的一个端点是最大值,而另一个端点不是次大值,那么将获得 \(p_2\) 的价值。
\(1\leq n,m\leq 200000\)
Solution
显然,两种情况都需要满足其中一个端点是最大值。我们可以用单调栈预处理出两个数组 \(l_i,r_i\) 分别表示左边第一个比 \(K_i\) 大的数的位置,以及右边第一个比 \(K_i\) 大的数的位置。
显然我们枚举位置 \(i\) 时,满足:
- 左端点为 \(l_i\) 右端点为 \(r_i\) 时,这个区间贡献为 \(p_1\) ;
- 左端点为 \(l_i\) 右端点在 \((i,r_i)\) 之间时,贡献为 \(p_2\) ;
- 左端点在 \((l_i, i)\) 之间时,右端点为 \(r_i\) ,贡献为 \(p_2\)
然后就是扫描线来处理所有询问了。
因为单调队列的 \(while\) 写成 \(if\) 调了一下午。
Code
//It is made by Awson on 2018.3.6
#include <bits/stdc++.h>
#define LL long long
using namespace std;
const int N = 200000;
int n, m, p1, p2, a[N+5], l[N+5], r[N+5], S[N+5], top, cnt; LL ans[N+5];
struct Segment_tree {
#define lr(o) (o<<1)
#define rr(o) (o<<1|1)
LL key[(N<<2)+5], lazy[(N<<2)+5];
void pushdown(int o, int l, int r, int mid) {
key[lr(o)] += 1ll*(mid-l+1)*lazy[o];
key[rr(o)] += 1ll*(r-mid)*lazy[o];
lazy[lr(o)] += lazy[o], lazy[rr(o)] += lazy[o];
lazy[o] = 0;
}
void update(int o, int l, int r, int a, int b, int k) {
if (a <= l && r <= b) {key[o] += 1ll*(r-l+1)*k, lazy[o] += k; return; }
int mid = (l+r)>>1; if (lazy[o]) pushdown(o, l, r, mid);
if (a <= mid) update(lr(o), l, mid, a, b, k);
if (b > mid) update(rr(o), mid+1, r, a, b, k);
key[o] = key[lr(o)]+key[rr(o)];
}
LL query(int o, int l, int r, int a, int b) {
if (a <= l && r <= b) return key[o]; int mid = (l+r)>>1;
if (lazy[o]) pushdown(o, l, r, mid); LL c1 = 0, c2 = 0;
if (a <= mid) c1 = query(lr(o), l, mid, a, b);
if (b > mid) c2 = query(rr(o), mid+1, r, a, b);
return c1+c2;
}
}T;
struct opts {
int l, r, t, id, p;
bool operator < (const opts &b) const {return t < b.t; }
}s1[N*2+5], s2[N*3+5];
void work() {
scanf("%d%d%d%d", &n, &m, &p1, &p2);
for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
for (int i = 1; i <= m; i++) {
int l, r;
scanf("%d%d", &l, &r); ans[i] = 1ll*(r-l)*p1;
s1[i].l = l, s1[i].r = r, s1[i].t = l-1, s1[i].id = i, s1[i].p = -1;
s1[i+m].l = l, s1[i+m].r = r, s1[i+m].t = r, s1[i+m].id = i, s1[i+m].p = 1;
}
top = 0;
for (int i = 1; i <= n; i++) {
while (top > 0 && a[i] > a[S[top]]) --top;
l[i] = (top == 0 ? 0 : S[top]); S[++top] = i;
}
top = 0;
for (int i = n; i >= 1; i--) {
while (top > 0 && a[i] > a[S[top]]) --top;
r[i] = top == 0 ? n+1 : S[top]; S[++top] = i;
}
for (int i = 1; i <= n; i++) {
if (l[i] != 0 && r[i] != n+1) s2[++cnt].l = s2[cnt].r = r[i], s2[cnt].t = l[i], s2[cnt].p = p1;
if (l[i] != 0 && r[i] > i+1) s2[++cnt].l = i+1, s2[cnt].r = r[i]-1, s2[cnt].t = l[i], s2[cnt].p = p2;
if (l[i] < i-1 && r[i] != n+1) s2[++cnt].l = l[i]+1, s2[cnt].r = i-1, s2[cnt].t = r[i], s2[cnt].p = p2;
}
sort(s1+1, s1+2*m+1); sort(s2+1, s2+cnt+1);
int n1 = 1, n2 = 1;
while (n1 <= 2*m) {
while (n2 <= cnt && s2[n2].t <= s1[n1].t) T.update(1, 1, n, s2[n2].l, s2[n2].r, s2[n2].p), ++n2;
while (n1 <= 2*m && (s1[n1].t < s2[n2].t || n2 > cnt)) ans[s1[n1].id] += 1ll*T.query(1, 1, n, s1[n1].l, s1[n1].r)*s1[n1].p, ++n1;
}
for (int i = 1; i <= m; i++) printf("%lld\n", ans[i]);
}
int main() {
work(); return 0;
}
[HNOI 2017]影魔的更多相关文章
- [HNOI/AHOI2017]影魔
[HNOI/AHOI2017]影魔 题目大意: 有一排\(n(n\le2\times10^5)\)个数\(k_{1\sim n}\).对于点对\((i,j)\),若不存在\(k_s(i<s< ...
- 【HNOI 2017】影魔
Problem Description 影魔,奈文摩尔,据说有着一个诗人的灵魂.事实上,他吞噬的诗人灵魂早已成千上万.千百年来,他收集了各式各样的灵魂,包括诗人.牧师.帝王.乞丐.奴隶.罪人,当然,还 ...
- [HNOI 2017]单旋
Description H 国是一个热爱写代码的国家,那里的人们很小去学校学习写各种各样的数据结构.伸展树(splay)是一种数据 结构,因为代码好写,功能多,效率高,掌握这种数据结构成为了 H 国的 ...
- [HNOI 2017]抛硬币
Description 题库链接 两人抛硬币一人 \(a\) 次,一人 \(b\) 次.记正面朝上多的为胜.问抛出 \(a\) 次的人胜出的方案数. \(1\le a,b\le 10^{15},b\l ...
- [HNOI 2017]礼物
Description 我的室友最近喜欢上了一个可爱的小女生.马上就要到她的生日了,他决定买一对情侣手 环,一个留给自己,一个送给她.每个手环上各有 n 个装饰物,并且每个装饰物都有一定的亮度.但是在 ...
- 【HNOI 2017】大佬
Problem Description 人们总是难免会碰到大佬.他们趾高气昂地谈论凡人不能理解的算法和数据结构,走到任何一个地方,大佬的气场就能让周围的人吓得瑟瑟发抖,不敢言语.你作为一个 OIer, ...
- HNOI 2017
题目链接 我还是按bzoj AC数量排序做的 4827 这个其实如果推一下(求每个值)式子会发现是个卷积,然后FFT就好了 4826 记不太清了,可以求出每个点左右第一个比他的的点的位置,将点对看成平 ...
- 【HNOI 2017】礼物
Problem Description 我的室友最近喜欢上了一个可爱的小女生.马上就要到她的生日了,他决定买一对情侣手环,一个留给自己,一个送给她.每个手环上各有 \(n\) 个装饰物,并且每个装饰物 ...
- [HNOI 2017]大佬
Description 题库链接 题意简述来自Gypsophila. 你现在要怼 \(m\) 个大佬,第 \(i\) 个大佬的自信值是 \(C_i\) .每次怼大佬之前,你的自信值是 \(mc\),等 ...
随机推荐
- Alpha冲刺No.5
一.站立式会议 在助教帮助下,优先解决404的问题,将demo移植到自己项目上. 进一步制作界面. 将已做好的内容,移植到手机做部分测试,能够在同一路由子网内登录数据库. 二.实际项目进展 已经解决了 ...
- python pdb 调试
命令行 Python -m pdb xxx.py l ----> list 显示当前代码 n ----> next 向下执行一行代码 c ----> continue 继续执行代码 ...
- 修改MYSQL的默认连接时长
show global variables like 'wait_timeout'; 设置成10小时; set global wait_timeout=36000;
- css精简命名
想写写前言啥的,发现自己是前言无能星人. 简单吐吐槽好了,来到新公司,接手公司之前的项目,我想着也就是改改bug,慢慢来吧,粗略看了看这个项目的代码,目前仅看了html和css样式的,忍不住吐血三升. ...
- PV & PVC - 每天5分钟玩转 Docker 容器技术(150)
Volume 提供了非常好的数据持久化方案,不过在可管理性上还有不足. 拿前面 AWS EBS 的例子来说,要使用 Volume,Pod 必须事先知道如下信息: 当前 Volume 来自 AWS EB ...
- RE:1054652545 - 论自己是如何蠢死的
1.Java web 项目中 login/list 文件夹中return "login/list" 反复读取不到对应的jsp文件 一周后检查出来的原因上一级文件夹login前面多出 ...
- MySQL 主从复制那些事(一)
本部分主要以理论为主,具体的主从搭建环境,大家可以参考博客其他部分.下面我就给大家数说主从复制那些理论的东西.说的不一定都是正确的,有不同出入的地方,欢迎大家一起交流沟通,以下我把我自己整理出来的主从 ...
- Python内置函数(15)——memoryview
英文文档: class memoryview(obj) memoryview objects allow Python code to access the internal data of an o ...
- ArrayList、Vector、LinkedList、HashMap、HashTable的存储性能和特性
ArrayList和Vector都是使用数组方式存储数据,次数组元素大于实际存储的数据以便添加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数 ...
- 微信小程序组件学习中
一.轮播图 wxml代码: <swiper indicator-dots="true" autoplay="true" duration="10 ...