BZOJ 4826: [Hnoi2017]影魔 单调栈 主席树
https://www.lydsy.com/JudgeOnline/problem.php?id=4826
年少不知空间贵,相顾mle空流泪。
和上一道主席树求的东西差不多,求两种对
1. max(a[(i,j)])<min(a[i],a[j]),[i,j]这一对贡献p1.
2. max(a[(i,j)])在a[i],a[j]之间,[i,j]这一对贡献p2.
第一种和bzoj3956那道一样,但是因为是排列所以没必要去重了。
第二种同样是单调栈求lp,rp,每个位置的lp分别和[ i+1 , rp-1 ], rp分别和[ lp+1 , i-1 ], 构成了贡献p2的数对。
因此贡献为p2的数对要区间修改,因为方便(不用downdata)(其实是因为我抄的代码就是标记永久化)所以写了标记永久化,标记永久化真的挺好用的嘻嘻。
感觉写了这道题终于有点摸到主席树的门路了,其实就是找和维护两个区间进行限制的值(找和维护一个二维块),一层线段树一层前缀和(只是有传递性不一定是实际意义的和)。
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 using namespace std; 7 #define LL long long 8 const int maxn=200010; 9 LL n,m,p1,p2; 10 LL a[maxn]={},sta[maxn]={},tail=0; 11 LL lp[maxn]={},rp[maxn]={},rt[maxn]={}; 12 LL lc[maxn*64]={},rc[maxn*64]={},siz[maxn*64]={},ad[maxn*64]={},tot=0; 13 struct nod{ 14 LL x,l,r,v; 15 }e[maxn*4]; 16 LL cnt=0; 17 bool mcmp(nod aa,nod bb){ return aa.x<bb.x; } 18 LL read(){ 19 LL w=0,f=1;char ch=getchar(); 20 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 21 while(ch>='0'&&ch<='9'){w=w*10+ch-'0';ch=getchar();} 22 return w*f; 23 } 24 void build(LL &x,LL y,LL l,LL r,LL z,LL zl,LL zr){ 25 x=++tot;lc[x]=lc[y];rc[x]=rc[y];ad[x]=ad[y];siz[x]=siz[y]+z*(zr-zl+1); 26 if(zl==l&&r==zr){ad[x]+=z;return;} 27 LL mid=(l+r)/2; 28 if(zr<=mid)build(lc[x],lc[y],l,mid,z,zl,zr); 29 else if(zl>mid) build(rc[x],rc[y],mid+1,r,z,zl,zr); 30 else { 31 build(lc[x],lc[y],l,mid,z,zl,mid); 32 build(rc[x],rc[y],mid+1,r,z,mid+1,zr); 33 } 34 } 35 LL getsum(LL x,LL y,LL l,LL r,LL zl,LL zr){ 36 if(zl==l&&r==zr)return siz[y]-siz[x]; 37 LL mid=(l+r)/2,ans=(ad[y]-ad[x])*(zr-zl+1); 38 if(zr<=mid)return ans+getsum(lc[x],lc[y],l,mid,zl,zr); 39 else if(zl>mid) return ans+getsum(rc[x],rc[y],mid+1,r,zl,zr); 40 else { 41 return ans+getsum(lc[x],lc[y],l,mid,zl,mid)+getsum(rc[x],rc[y],mid+1,r,mid+1,zr); 42 } 43 } 44 //以上主席树 45 inline void fir(){ 46 LL i; 47 a[0]=a[n+1]=(1<<30); 48 for(i=1;i<=n;++i){ 49 while(a[sta[tail]]<=a[i])tail--; 50 lp[i]=sta[tail];sta[++tail]=i; 51 } 52 sta[0]=n+1;tail=0; 53 for(i=n;i>0;--i){ 54 while(a[sta[tail]]<=a[i])tail--; 55 rp[i]=sta[tail];sta[++tail]=i; 56 } 57 } 58 inline void init(LL x,LL l,LL r,LL v){ 59 e[++cnt].x=x;e[cnt].l=l;e[cnt].r=r;e[cnt].v=v; 60 } 61 inline void fir2(){ 62 LL i,j; 63 for(i=1;i<=n;++i){ 64 if(lp[i]!=0&&rp[i]!=n+1)init(lp[i],rp[i],rp[i],p1); 65 if(i<n)init(i,i+1,i+1,p1); 66 if(lp[i]!=0&&rp[i]-i>1)init(lp[i],i+1,rp[i]-1,p2); 67 if(rp[i]!=n+1&&i-lp[i]>1)init(rp[i],lp[i]+1,i-1,p2); 68 } 69 sort(e+1,e+cnt+1,mcmp); 70 for(i=j=1;i<=n;++i){ 71 rt[i]=rt[i-1]; 72 for(;e[j].x==i&&j<=cnt;++j)build(rt[i],rt[i],1,n,e[j].v,e[j].l,e[j].r); 73 } 74 } 75 int main(){ 76 LL i,x,y,ans=0; 77 n=read();m=read();p1=read();p2=read(); 78 for(i=1;i<=n;++i)a[i]=read(); 79 fir(); fir2(); 80 for(i=1;i<=m;++i){ 81 x=read();y=read(); 82 if(x>y)swap(x,y); 83 ans=getsum(rt[x-1],rt[y],1,n,x,y); 84 printf("%lld\n",ans); 85 } 86 return 0; 87 }
View Code
转载于:https://www.cnblogs.com/137shoebills/p/8794916.html
BZOJ 4826: [Hnoi2017]影魔 单调栈 主席树相关推荐
- 【BZOJ4826】[Hnoi2017]影魔 单调栈+扫描线
[BZOJ4826][Hnoi2017]影魔 Description 影魔,奈文摩尔,据说有着一个诗人的灵魂.事实上,他吞噬的诗人灵魂早已成千上万.千百年来,他收集了各式各样的灵魂,包括诗人.牧师.帝 ...
- bzoj 4826: [Hnoi2017]影魔
Description 影魔,奈文摩尔,据说有着一个诗人的灵魂.事实上,他吞噬的诗人灵魂早已成千上万.千百年来,他收集了各式各样 的灵魂,包括诗人.牧师.帝王.乞丐.奴隶.罪人,当然,还有英雄.每一个 ...
- bzoj 4826 [Hnoi2017]影魔
http://www.elijahqi.win/archives/3687 Description 影魔,奈文摩尔,据说有着一个诗人的灵魂.事实上,他吞噬的诗人灵魂早已成千上万.千百年来,他收集了各式 ...
- [CF 526 F] Pudding Monsters(单调栈 + 线段树)
CF526F Pudding Monsters problem solution code problem luogu翻译 solution observation :每行每列恰好有一个棋子,所以如果 ...
- 【BZOJ】3956 Count 单调栈+ST表
题目传送门 挺有思想的一题,但如果弄清楚了思路这题还是挺简单的. 首先我们可以发挥一下自己的脑洞,发现所有的好集对不可能相交. 那么我们可以刷两遍单调栈,求出每个点作为区间左端点或右端点的次数. 对于 ...
- 2019南昌网络赛-I(单调栈+线段树)
题目链接:https://nanti.jisuanke.com/t/38228 题意:定义一段区间的值为该区间的和×该区间的最小值,求给定数组的最大的区间值. 思路:比赛时还不会线段树,和队友在这题上 ...
- HDU - 6989 Didn‘t I Say to Make My Abilities Average in the Next Life?! 莫队/单调栈 + 线段树/ST表在线
传送门 文章目录 题意: 思路: 题意: 思路: 考虑将贡献分开来算,先计算最大值,再算个最小值,之后答案就是((max+min)/2)/(len∗(len+1)/2)((max+min)/2)/(l ...
- [LOJ3153] 三级跳(单调栈 + 线段树)
problem loj3153 solution 有一个显然正确但又不起眼却是正解必备的结论: 考虑 (x,y,z)(x,y,z)(x,y,z) 答案三元对,如果有一个数 i∈(x,y)∧ai≥axi ...
- 扶桑号战列舰【单调栈+线段树】
扶桑号战列舰 传送门 来源upc:12800 题目描述 众所周知,一战过后,在世界列强建造超无畏级战列舰的竞争之中,旧日本海军根据"个舰优越主义",建造了扶桑级战列舰,完工时为当 ...
最新文章
- IntelliTest(5) - The IntelliTest Reference Manual[译]
- 分享一下dudu回答的一个方法
- MFCButton Memory leak(内存泄露问题)
- c#app.config配置文件使用
- java 队列总结queue v3 svv.docxjava 队列总结queue v3 svv.docx atitit. java queue 队列体系总结o7t 1. 队列概念	1 1.1. 队列
- 【车间调度】基于matlab模拟退火算法求解车间调度问题【含Matlab源码 894期】
- .net mvc html.row,ASP.NET MVC4中的WebGrid
- 微信小程序选项卡页面切换
- cloud2声卡_带你解惑HyperX Cloud2(飓风)和Alpha(阿尔法)的终极选择
- 高通蓝牙耳机开发方法-周康
- 在自己本地原有的镜像基础上用dockerfile加一下库进去
- 鼠标自动点击工具鼠标连点器鼠标定时自动点击使用方法
- 沃商店运营一周年凸显平台化优势
- 099node-MongoDB数据库添加账户
- 洛谷P1460 健康的荷斯坦奶牛
- 人——Web3的新平台
- Homekit智能家居DIY设备一智能灯泡
- uniapp 二维码展示和扫码
- 游戏抽奖界面html,基于JavaScript实现幸运抽奖页面
- go swag常用注释
热门文章
- python 调用 C++ code
- MDT2012+ADK8.0+WDS部署Windows客户端(一)部署概念和方法论
- L1-074 两小时学完C语言 (5 分)-PAT 团体程序设计天梯赛 GPLT
- PAT 乙级 1001. 害死人不偿命的(3n+1)猜想 (15) Java版
- LeetCode 454. 4Sum II
- 外点罚函数matlab程序_关于图像轮廓识别的程序实现
- python通过SNMP协议收集服务器监控信息(安装、配置、示例)
- Spring Cloud Zuul--服务网关
- 并发 --- 32 管道 事件 信号量 进程池
- MYSQL存储过程中事务和DECLARE EXIT/CONTINUE HANDLER的使用