Description

题库链接

给你一段长度为 \(n\) 的序列 \(K\) 。 \(m\) 组询问,每次给定左右端点 \(l,r\) 。求出满足区间内下述贡献和。

  1. 如果一个区间的两个端点是这一个区间的最大与次大值,那么将获得 \(p_1\) 的价值;
  2. 如果一个区间的一个端点是最大值,而另一个端点不是次大值,那么将获得 \(p_2\) 的价值。

\(1\leq n,m\leq 200000\)

Solution

显然,两种情况都需要满足其中一个端点是最大值。我们可以用单调栈预处理出两个数组 \(l_i,r_i\) 分别表示左边第一个比 \(K_i\) 大的数的位置,以及右边第一个比 \(K_i\) 大的数的位置。

显然我们枚举位置 \(i\) 时,满足:

  1. 左端点为 \(l_i\) 右端点为 \(r_i\) 时,这个区间贡献为 \(p_1\) ;
  2. 左端点为 \(l_i\) 右端点在 \((i,r_i)\) 之间时,贡献为 \(p_2\) ;
  3. 左端点在 \((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]影魔的更多相关文章

  1. [HNOI/AHOI2017]影魔

    [HNOI/AHOI2017]影魔 题目大意: 有一排\(n(n\le2\times10^5)\)个数\(k_{1\sim n}\).对于点对\((i,j)\),若不存在\(k_s(i<s< ...

  2. 【HNOI 2017】影魔

    Problem Description 影魔,奈文摩尔,据说有着一个诗人的灵魂.事实上,他吞噬的诗人灵魂早已成千上万.千百年来,他收集了各式各样的灵魂,包括诗人.牧师.帝王.乞丐.奴隶.罪人,当然,还 ...

  3. [HNOI 2017]单旋

    Description H 国是一个热爱写代码的国家,那里的人们很小去学校学习写各种各样的数据结构.伸展树(splay)是一种数据 结构,因为代码好写,功能多,效率高,掌握这种数据结构成为了 H 国的 ...

  4. [HNOI 2017]抛硬币

    Description 题库链接 两人抛硬币一人 \(a\) 次,一人 \(b\) 次.记正面朝上多的为胜.问抛出 \(a\) 次的人胜出的方案数. \(1\le a,b\le 10^{15},b\l ...

  5. [HNOI 2017]礼物

    Description 我的室友最近喜欢上了一个可爱的小女生.马上就要到她的生日了,他决定买一对情侣手 环,一个留给自己,一个送给她.每个手环上各有 n 个装饰物,并且每个装饰物都有一定的亮度.但是在 ...

  6. 【HNOI 2017】大佬

    Problem Description 人们总是难免会碰到大佬.他们趾高气昂地谈论凡人不能理解的算法和数据结构,走到任何一个地方,大佬的气场就能让周围的人吓得瑟瑟发抖,不敢言语.你作为一个 OIer, ...

  7. HNOI 2017

    题目链接 我还是按bzoj AC数量排序做的 4827 这个其实如果推一下(求每个值)式子会发现是个卷积,然后FFT就好了 4826 记不太清了,可以求出每个点左右第一个比他的的点的位置,将点对看成平 ...

  8. 【HNOI 2017】礼物

    Problem Description 我的室友最近喜欢上了一个可爱的小女生.马上就要到她的生日了,他决定买一对情侣手环,一个留给自己,一个送给她.每个手环上各有 \(n\) 个装饰物,并且每个装饰物 ...

  9. [HNOI 2017]大佬

    Description 题库链接 题意简述来自Gypsophila. 你现在要怼 \(m\) 个大佬,第 \(i\) 个大佬的自信值是 \(C_i\) .每次怼大佬之前,你的自信值是 \(mc\),等 ...

随机推荐

  1. IO流回顾与总结第一篇之字节流与字符流的操作。。。。。

    一.引言 趁着年后的这点时间,抓紧点时间回顾下javase中的IO流,以往都是用到那些常用的IO类,这次来个全点的,有不对的地方还请大神指正一下,做到坚持写博的习惯来...... 回归正题,IO流顾名 ...

  2. 201621123031 《Java程序设计》第11周学习总结

    作业11-多线程 1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容. 2. 书面作业 本次PTA作业题集多线程 1. 源代码阅读:多线程程序BounceThread ...

  3. 201621123031 《Java程序设计》第5周学习总结

    作业05-继承.多态.抽象类与接口 1. 本周学习总结 1.1 写出你认为本周学习中比较重要的知识点关键词 关键字:接口.继承.多态 1.2 尝试使用思维导图将这些关键词组织起来.注:思维导图一般不需 ...

  4. bzoj千题计划219:bzoj1568: [JSOI2008]Blue Mary开公司

    http://www.lydsy.com/JudgeOnline/problem.php?id=1568 写多了就觉着水了... #include<cstdio> #include< ...

  5. Ubuntu命令行连接WPA/WPA2无线网线

    一,连接无加密无线网络zhang:sudo ip link set wlan0 up sudo iw dev wlan0 connect zhangsudo dhclient wlan0 二,连接WP ...

  6. @SpringBootApplication 组合注解包含哪些注解及作用

    序:在学习springboot,教程一般对一些注解语焉不详,发现@SpringBootApplication 这个注解包含了很多注解,也就是说使用这个注解可以少写几个注解,这里看源码粘出来一些,仅用于 ...

  7. You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'like '%逸%'' at line 1

    <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-/ ...

  8. AutoCAD中的扩展字典及扩展记录(C#)

    在学习CAD扩展记录的过程中,遇到了一些问题,也积累了一些经验,现在给大家分享一些我的学习心得.在学习扩展字典之前需要读者了解cad的组码,也就是DxfCode.感兴趣的也可以了解一下扩展数据的相关内 ...

  9. SSH 配置

    ssh免密通用配置 Host * Port 1234 User root #ProxyCommand nc -X 5 -x 127.0.0.1:1081 %h %p #5 socks5, 4 sock ...

  10. Spring Security 入门(1-2)Spring Security - 从 配置例子例子 开始我们的学习历程

    1.Spring Security 的配置文件 我们需要为 Spring Security 专门建立一个 Spring 的配置文件,该文件就专门用来作为 Spring Security 的配置. &l ...