[HNOI2017]影魔
题意:
给定 \(n\) 个数的排列,\(m\) 次询问,每次询问询问一个区间内所有子区间的贡献。
每个区间如果两个端点分别是最大值和次大值,我们就算 \(P1\) 的贡献。
如果两个端点一个是最大值,一个不是次大值,我们就算 \(P2\) 的贡献。
\(\text{Solution:}\)
将询问离线,处理出以 \(i\) 结尾的询问的答案。
考虑怎样的点 \(j(j<i)\) 满足它能与 \(i\) 组成区间 \(i\) ,\(j\) 分别是最大值与次大值或非次大值。
钦定 \(a[i]\) 比 \(a[j]\) 大,那么当 \(a[j]\) 为左边单调减的波峰的时候与 \(a[i]\) 有贡献 \(p1\) ,当 \(a[j]\) 为左边两个单调减的波峰之间的时候与 \(a[i]\) 有贡献 \(p2\) 。
维护单调减的波峰可以用单调栈。
由于钦定了 \(a[i] > a[j]\) 所以要倒过来再搞一遍。
像这种区间上不好直接维护的东西,可以考虑离线,讨论时要讨论清楚哪种点有贡献。
\(\text{Source:}\)
#include<vector>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <assert.h>
#include <algorithm>
using namespace std;
#define LL long long
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define GO debug("GO\n")
inline int rint() {
register int x = 0, f = 1; register char c;
while (!isdigit(c = getchar())) if (c == '-') f = -1;
while (x = (x << 1) + (x << 3) + (c ^ 48), isdigit(c = getchar()));
return x * f;
}
template<typename T> inline void chkmin(T &a, T b) { a > b ? a = b : 0; }
template<typename T> inline void chkmax(T &a, T b) { a < b ? a = b : 0; }
const int N = 2e5 + 10;
int n,m,p1,p2;
int a[N];
vector<pair<int,int> >Q,QR[N];
LL ans[N];
namespace SGT {
#define ls (x<<1)
#define rs (x<<1|1)
LL sum[N * 4], tag[N * 4];
void init() {
memset(sum, 0, sizeof sum);
memset(tag, 0, sizeof tag);
}
void pu(int x) {
sum[x] = sum[ls] + sum[rs];
}
void pd(int x, int l, int r) {
if (tag[x]) {
int mid = (l + r) >> 1;
sum[ls] += tag[x] * (mid - l + 1);
tag[ls] += tag[x];
sum[rs] += tag[x] * (r - mid);
tag[rs] += tag[x];
tag[x] = 0;
}
}
void Add(int L, int R, int val, int x = 1, int l = 1, int r = n) {
if (L > R) return;
if (L <= l and r <= R) {
sum[x] += val * (r - l + 1);
tag[x] += val;
return;
}
pd(x, l, r); int mid = (l + r) >> 1;
if (L <= mid) Add(L, R, val, ls, l, mid);
if (R > mid) Add(L, R, val, rs, mid + 1, r);
pu(x);
}
LL query(int L, int R, int x = 1, int l = 1, int r = n) {
if (L > R) return 0;
if (L <= l and r <= R) {
return sum[x];
}
pd(x, l, r); int mid = l + r >> 1;
LL ans = 0;
if (L <= mid) ans += query(L, R, ls, l, mid);
if (mid < R) ans += query(L, R, rs, mid + 1, r);
return ans;
}
}using SGT::Add; using SGT::query;
void work() {
static int stk[N], top;
SGT::init();
top = 0;
for (int i = 1; i <= n; ++ i) {
int last = i;
while (top and a[stk[top]] <= a[i]) {
if (stk[top] + 1 < last)
Add(stk[top] + 1, last - 1, p2);
Add(stk[top], stk[top], p1);
last = stk[top--];
}
if (!top) Add(1, last - 1, p2);
else Add(stk[top] + 1, last - 1, p2);
stk[++top] = i;
for (int j = 0; j < QR[i].size(); ++ j)
ans[QR[i][j].second] += query(QR[i][j].first, i);
}
}
int main(){
#ifndef ONLINE_JUDGE
freopen("xhc.in", "r", stdin);
freopen("xhc.out", "w", stdout);
#endif
n = rint(), m = rint(), p1 = rint(), p2 = rint();
for (int i = 1; i <= n; ++ i) a[i] = rint();
for (int i = 1; i <= m; ++ i){
int l = rint(), r = rint();
Q.push_back(make_pair(l, r));
}
for (int i = 0; i < m; ++ i)
QR[Q[i].second].push_back(make_pair(Q[i].first, i + 1));
work();
for (int i = 1; i <= n; ++ i)
QR[i].clear();
for (int i = 0; i < m; ++ i)
QR[n - Q[i].first + 1].push_back(make_pair(n - Q[i].second + 1, i + 1));
reverse(a + 1, a + 1 + n);
work();
for (int i = 1; i <= m; ++ i) printf("%lld\n", ans[i]);
}
[HNOI2017]影魔的更多相关文章
- bzoj 4826: [Hnoi2017]影魔 [主席树 单调栈]
4826: [Hnoi2017]影魔 题意:一个排列,点对\((i,j)\),\(p=max(i+1,j-1)\),若\(p<a_i,a_j\)贡献p1,若\(p\)在\(a_1,a_2\)之间 ...
- 4826: [Hnoi2017]影魔
4826: [Hnoi2017]影魔 https://lydsy.com/JudgeOnline/problem.php?id=4826 分析: 莫队+单调栈+st表. 考虑如何O(1)加入一个点,删 ...
- 【LG3722】[HNOI2017]影魔
[LG3722][HNOI2017]影魔 题面 洛谷 题解 先使用单调栈求出\(i\)左边第一个比\(i\)大的位置\(lp_i\),和右边第一个比\(i\)大的位置\(rp_i\). 考虑\(i\) ...
- [BZOJ4826][HNOI2017]影魔(主席树)
4826: [Hnoi2017]影魔 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 669 Solved: 384[Submit][Status][ ...
- 【BZOJ4826】[Hnoi2017]影魔 单调栈+扫描线
[BZOJ4826][Hnoi2017]影魔 Description 影魔,奈文摩尔,据说有着一个诗人的灵魂.事实上,他吞噬的诗人灵魂早已成千上万.千百年来,他收集了各式各样的灵魂,包括诗人.牧师.帝 ...
- [bzoj4826][Hnoi2017]影魔_单调栈_主席树
影魔 bzoj-4826 Hnoi-2017 题目大意:给定一个$n$个数的序列$a$,求满足一下情况的点对个数: 注释:$1\le n,m\le 2\cdot 10^5$,$1\le p1,p2\l ...
- bzoj4826 [Hnoi2017]影魔
Description 影魔,奈文摩尔,据说有着一个诗人的灵魂.事实上,他吞噬的诗人灵魂早已成千上万.千百年来,他收集了各式各样的灵魂,包括诗人.牧师.帝王.乞丐.奴隶.罪人,当然,还有英雄.每一个灵 ...
- BZOJ:4826: [Hnoi2017]影魔
Description 影魔,奈文摩尔,据说有着一个诗人的灵魂.事实上,他吞噬的诗人灵魂早已成千上万.千百年来,他收集了各式各样的灵魂,包括诗人.牧师.帝王.乞丐.奴隶.罪人,当然,还有英雄.每一个灵 ...
- [AH/HNOI2017]影魔
题目背景 影魔,奈文摩尔,据说有着一个诗人的灵魂. 事实上,他吞噬的诗人灵魂早已成千上万. 千百年来,他收集了各式各样的灵魂,包括诗人. 牧师. 帝王. 乞丐. 奴隶. 罪人,当然,还有英雄. 题目描 ...
- HNOI2017影魔
影魔 这么简单的方法尽然想不到,我是真的菜 对每个点,用单调栈的方式处理出他左右第一个比他大的数的位置,你可以把\(0\)和\(n+1\)设成\(inf\). 显然对于每对\(lef[i]\)和\(r ...
随机推荐
- 关于session序列化和session钝化和活化
在第一次启动服务器后,在session中放入一个对象.在页面可以获得,当重启服务器,但是没有关闭浏览器的情况下刷新页面仍然能够获得这个对象,前提是这个对象必须实现了java.io.Serializab ...
- win10系统下多python版本部署
说明:win10,已安装有python3.5.2,为使用新浪云应用(SAE)支持微信公众号后台开发(SAE的python运行环境使用的是2.7.9),需部署python2.7的版本以便本地编辑调试. ...
- iOS universallinks唤醒app
从iOS9之后,苹果就推出了这个功能,用来唤醒外部app.这个功能在那些电商app上使用尤其广泛,当你打开对应的h5网页后,上面跳出一个是否跳转app的按钮. 现在iOS11已经基本覆盖,iOS12也 ...
- 通过非聚集索引让select count(*) from 的查询速度提高几十倍、甚至千倍
通过非聚集索引,可以显著提升count(*)查询的性能. 有的人可能会说,这个count(*)能用上索引吗,这个count(*)应该是通过表扫描来一个一个的统计,索引有用吗? 不错,一般的查询,如果用 ...
- you don't have permission to access ...........on this server问题解决
因为刚刚开始使用新架构的项目,于是把老项目统统替换成了新的项目.配置好后,本地登录页面报 you don't have permission to access ...... on this serv ...
- JavaScript变量声明及赋值
1.变量声明 var a; //声明一个变量 a var b,c,d; //同时申明多个变量时,变量名之间用逗号隔开 console.log(a); //在控制台显示变量a的值,输出为undefine ...
- dnspy的详细配置,dnspy如何过滤反编译之后的乱码,dnspy如何反编译表达式目录树
dnSpy应该是目前使用最多的.net反编译工具.很多情况下反编译C#代码非常方便,特别是查找基类,子类.搜索一些class,方法.接口,非常方便.比ILspy好很多.而且dnspy是可以配置的. 如 ...
- 09.安装Collabora Online服务
安装Collabora Online服务 参考博客:http://blog.sina.com.cn/s/blog_16b158be80102xp5u.html 一.安装docker服务 yum ins ...
- Linq 综合写法
var queryCount = (from pv in db.Province join pc in (from cc in ((from v in db.ERPStockProdu ...
- hive常见的几种优化手段
Hive调优的几个入手点: Hive是基于Hadoop框架的,Hadoop框架又是运行在JVM中的,而JVM最终是要运行在操作系统之上的,所以,Hive的调优可以通过如下几个方面入手: 操作系统调优 ...