BZOJ 4826 【HNOI2017】 影魔
题目链接:影魔
这道题就是去年序列的弱化版啊……
我们枚举最大值的位置\(i\),找出左边第一个比\(a_i\)大的位置\(l\),右边第一个比\(a_i\)大的位置\(r\),然后我们分开考虑一下\(p_1\)和\(p_2\)的贡献。
首先由于\(a_i\)为最大值,那么左端点不会小于\(l\),右端点不会大于\(r\)。
容易发现只有左端点为\(l\),右端点为\(r\)才会产生\(p_1\)的贡献。
然后产生\(p_2\)贡献的有两种:一种是左端点为\(l\),右端点在区间\((i,r)\)中;另一种是左端点区间\((l,i)\)中,右端点为\(r\)。
还有一种情况需要考虑,就是左端点和右端点差为\(1\),会产生\(p_1\)的贡献。对每个询问直接计算就可以了。
所以这个问题可以抽象到二维平面上。有一些点和一些线段都有权值,每次询问某个矩形内部的权值和。
于是离线排序+扫描线+树状数组即可。
下面贴代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
#define maxn 200010 using namespace std;
typedef long long llg; struct data{
int l,r,x,b,z;
data(int A=0,int B=0,int C=0,int D=0,int E=0):l(A),r(B),x(C),b(D),z(E){}
bool operator < (const data &h)const{return x<h.x;}
}s1[maxn<<1],s2[maxn*3];
int n,m,p1,p2,S[maxn],top,ls;
int a[maxn],le[maxn],ri[maxn];
llg ans[maxn],c1[maxn],c2[maxn]; int getint(){
int w=0;bool q=0;
char c=getchar();
while((c>'9'||c<'0')&&c!='-') c=getchar();
if(c=='-') c=getchar(),q=1;
while(c>='0'&&c<='9') w=w*10+c-'0',c=getchar();
return q?-w:w;
} void add(int x,int y){for(int i=x;i<=n;i+=i&(-i)) c1[i]+=y,c2[i]+=1ll*x*y;}
llg sum(int x){
llg t=0;
for(int i=x;i;i-=i&(-i)) t+=(x+1)*c1[i]-c2[i];
return t;
} int main(){
File("sf");
scanf("%d %d %d %d",&n,&m,&p1,&p2);
a[0]=a[n+1]=n+1; S[top=1]=0;
for(int i=1;i<=n+1;i++){
if(i<=n) a[i]=getint();
while(a[S[top]]<a[i]) ri[S[top--]]=i;
le[i]=S[top]; S[++top]=i;
}
for(int i=1,l,r;i<=m;i++){
l=getint(),r=getint(); ans[i]+=(r-l)*p1;
s1[i]=data(l,r,l-1,i,-1);
s1[i+m]=data(l,r,r,i,1);
}
sort(s1+1,s1+m*2+1);
for(int i=1;i<=n;i++){
if(le[i] && ri[i]<=n) s2[++ls]=data(le[i],le[i],ri[i],0,p1);
if(le[i] && ri[i]>i+1) s2[++ls]=data(i+1,ri[i]-1,le[i],0,p2);
if(ri[i]<=n && i>le[i]+1) s2[++ls]=data(le[i]+1,i-1,ri[i],0,p2);
}
sort(s2+1,s2+ls+1); int n1=1,n2=1;
while(!s1[n1].x) n1++;
for(int i=1;n1<=m*2 && i<=n;i++){
while(n2<=ls && s2[n2].x==i){
add(s2[n2].r+1,-s2[n2].z);
add(s2[n2].l,s2[n2].z),n2++;
}
while(n1<=m*2 && s1[n1].x==i){
ans[s1[n1].b]+=s1[n1].z*(sum(s1[n1].r)-sum(s1[n1].l-1));
n1++;
}
}
for(int i=1;i<=m;i++) printf("%lld\n",ans[i]);
return 0;
}
BZOJ 4826 【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\)之间 ...
- BZOJ:4826: [Hnoi2017]影魔
Description 影魔,奈文摩尔,据说有着一个诗人的灵魂.事实上,他吞噬的诗人灵魂早已成千上万.千百年来,他收集了各式各样的灵魂,包括诗人.牧师.帝王.乞丐.奴隶.罪人,当然,还有英雄.每一个灵 ...
- ●BZOJ 4826 [Hnoi2017]影魔
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=4826 题解: 主席树,单调栈 以前还没做过这种维护信息的题,感觉好奇妙. 每对相邻的两个数所 ...
- BZOJ 4826: [Hnoi2017]影魔 单调栈 主席树
https://www.lydsy.com/JudgeOnline/problem.php?id=4826 年少不知空间贵,相顾mle空流泪. 和上一道主席树求的东西差不多,求两种对 1. max(a ...
- BZOJ 4826: [Hnoi2017]影魔 单调栈+可持久化线段树
Description 影魔,奈文摩尔,据说有着一个诗人的灵魂.事实上,他吞噬的诗人灵魂早已成千上万.千百年来,他收集了各式各样 的灵魂,包括诗人.牧师.帝王.乞丐.奴隶.罪人,当然,还有英雄.每一个 ...
- BZOJ 4826 [Hnoi2017]影魔 ——扫描线 单调栈
首先用单调栈和扫描线处理出每一个数左面最近的比他大的数在$l[i]$,右面最近的比他大的数$r[i]$. 然后就可以考虑每种贡献是在什么时候产生的. 1.$(l[i],r[i])$产生$p1$的贡献 ...
- bzoj 4826: [Hnoi2017]影魔【单调栈+树状数组+扫描线】
参考:https://www.cnblogs.com/lcf-2000/p/6789680.html 这是一个相对码量少的做法,用到了区间修改区间查询的树状数组,详见:www.cnblogs.com/ ...
- 4826: [Hnoi2017]影魔
4826: [Hnoi2017]影魔 https://lydsy.com/JudgeOnline/problem.php?id=4826 分析: 莫队+单调栈+st表. 考虑如何O(1)加入一个点,删 ...
- [BZOJ4826][HNOI2017]影魔(主席树)
4826: [Hnoi2017]影魔 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 669 Solved: 384[Submit][Status][ ...
- 【LG3722】[HNOI2017]影魔
[LG3722][HNOI2017]影魔 题面 洛谷 题解 先使用单调栈求出\(i\)左边第一个比\(i\)大的位置\(lp_i\),和右边第一个比\(i\)大的位置\(rp_i\). 考虑\(i\) ...
随机推荐
- Codeforce 814A - An abandoned sentiment from past (贪心)
A few years ago, Hitagi encountered a giant crab, who stole the whole of her body weight. Ever since ...
- [转载]Oracle PL/SQL之LOOP循环控制语句
在PL/SQL中可以使用LOOP语句对数据进行循环处理,利用该语句可以循环执行指定的语句序列.常用的LOOP循环语句包含3种形式:基本的LOOP.WHILE...LOOP和FOR...LOOP. LO ...
- 解决keepalived脑裂问题
检测思路:正常情况下keepalived的VIP地址是在主节点上的,如果在从节点发现了VIP,就设置报警信息 脚本如下: #!/bin/bash # 检查脑裂的脚本,在备节点上进行部署 LB01_VI ...
- react复习总结(2)--react生命周期和组件通信
这是react项目复习总结第二讲, 第一讲:https://www.cnblogs.com/wuhairui/p/10367620.html 首先我们来学习下react的生命周期(钩子)函数. 什么是 ...
- 开启redis-server提示 # Creating Server TCP listening socket *:6379: bind: Address already in use--解决方法
在bin目录中开启Redis服务器,完整提示如下: 3496:C 25 Apr 00:56:48.717 # Warning: no config file specified, using the ...
- hihocoder [Offer收割]编程练习赛14
A.小Hi和小Ho的礼物 谜之第1题,明明是第1题AC率比C还要低.题目是求在n个不同重量袋子选4袋,2袋给A,2袋给B,使2人获得重量相同,求问方案数. 我也是一脸懵b...o(n2)暴力枚举发现把 ...
- Netty1
基于Netty4的HttpServer和HttpClient的简单实现 Netty的主页:http://netty.io/index.html 使用的Netty的版本:netty-4.0.23.Fin ...
- 【题解】Luogu P4679 [ZJOI2011]道馆之战
原题传送门 码农题树剖好题,口袋妖怪是个好玩的游戏 这道题要用树链剖分,我博客里有对树链剖分的详细介绍 下文左右就代表树的节点按dfs序后的左右,上.下分别表示每个节点的A.B区域 考虑在链上的情况, ...
- linux服务器启动报错UNEXPECTED INCONSISTENCY解决方法
内网的linux服务器给开发员用来测试以及共享文件使用,今天早上发现xshell连接不上该服务器,一开始进入系统显示reboot and select proper boot device or in ...
- poj 1456 Supermarket - 并查集 - 贪心
题目传送门 传送点I 传送点II 题目大意 有$n$个商品可以销售.每个商品销售会获得一个利润,但也有一个时间限制.每个商品需要1天的时间销售,一天也只能销售一件商品.问最大获利. 考虑将出售每个物品 ...