「HNOI2017」影魔
题目描述
影魔,奈文摩尔,据说有着一个诗人的灵魂。事实上,他吞噬的诗人灵魂早已成千上万。千百年来,他收集了各式各样的灵魂,包括诗人、牧师、帝王、乞丐、奴隶、罪人,当然,还有英雄。
每一个灵魂,都有着自己的战斗力,而影魔,靠这些战斗力提升自己的攻击。
奈文摩尔有 $n$ 个灵魂,他们在影魔宽广的体内可以排成一排,从左至右标号 $1$ 到 $n$。第 $i$ 个灵魂的战斗力为 $k_i$,灵魂们以点对的形式为影魔提供攻击力,对于灵魂对 $i, j(i
影魔的挚友噬魂鬼在一天造访影魔体内时被这些灵魂吸引住了,他想知道,对于任意一段区间 $[a,b]$,位于这些区间中的灵魂对会为影魔提供多少攻击力,即考虑所有满足 $a\le i<j\le b$ 的灵魂对 $i, j$ 提供的攻击力之和。
顺带一提,灵魂的战斗力组成一个 $1$ 到 $n$ 的排列:$k_1, k_1, \cdots, k_n$。
输入格式
第一行四个整数 $n,m,p_1,p_2$;
第二行 $n$ 个整数数:$k_1, k_2,\cdots, k_n$;
接下来 $m$ 行,每行两个数 $a,b$,表示询问区间 $[a,b]$ 中的灵魂对会为影魔提供多少攻击力。
输出格式
共输出 $m$ 行,每行一个答案,依次对应 $m$ 个询问。
数据范围与提示
对于 $30\%$ 的数据,$1\le n, m\le 500$;
另有 $30\%$ 的数据,$p_1 = 2p_2$
对于 $100\%$ 的数据,$1\le n,m\le 200000, 1\le p_1, p_2\le 1000$。
首先简化一下题目:提供$p_1$的攻击力的区间要满足端点一个是区间最大值,另一个是区间次大值;提供$p_2$的攻击力的区间要满足其中一个端点是最大值,而另一个不是次大值。
对于第一类,考虑每个点作为区间端点且为次大值的情况,那么显然区间的另一个端点是它左边或右边第一个比它大的数。使用单调栈可以$O(n)$预处理出第$i$个数左边的第一个比它的位置$l[i]$,以及右边第一个比它大的位置$r[i]$。那么其中每有一个在$[a,b]$,就有1的贡献。
进一步转化模型,把每个$i$转为2个点$(i,l[i])$,$(i,r[i])$,那么每次询问的第一类区间个数就是左下角在$[a,a]$,右上角在$[b,b]$的矩形内的点的个数。
直接考虑第二类好像也可求?但是我是计算”其中一个端点是区间最大,另一个端点不做其他要求”的区间个数,用它来减去第一类的个数从而间接求。考虑每个数作为区间端点且为最大值的情况,那么区间的另一个端点一定落在$[l[i],i-1]\bigcup[i+1,r[i]]$中。
转换模型,每个点转为若干条横坐标为$i$的竖直线段,每次询问的就是左下角在$[a,a]$,右上角在$[b,b]$的矩形中,线段上的整点的个数。
两种类型都是扫描线的经典问题。可以考虑将询问离线,将矩形拆成前缀和相减的形式,再用线段树维护一下就好了。
1 |
|