线段树-Pudding Monster CF526F-单调栈

Pudding Monster

题目连接:https://www.luogu.org/problem/show?pid=CF526F

问题提出

  • 给长度为nnn的排列AAA.
  • 问有多少(l,r)(l,r)(l,r),使得将Al,Al+1,...,ArA_l,A_{l+1},...,A_rAl,Al+1,...,Ar排序之后是连续的一段数.
  • n≤105n \le 10^5n105

问题解决

判断一段区间是否能连续,只要判断是否满足max−min=r−lmax-min=r-lmaxmin=rl即可.

也即判断区间是否满足max−min+l=rmax-min+l = rmaxmin+l=r.

先天有max−min+l≥rmax-min+l \ge rmaxmin+lr

因此我们可以考虑枚举区间端点rrr,然后使用线段树维护左边所有区间(每个区间用左端点唯一标识)的l+max−minl+max-minl+maxmin的值.

我们还需要线段树满足求线段内最小值是谁,最小值有多少个的功能.

考虑到区间右端点向右移动的过程中,原有的区间再加上rrr形成的新区间的maxmaxmax不会变小,minminmin值不会变大.

maxmaxmax变大也会是一批区间一起增大,增量也是相同的,因此可以转化为区间修改操作.

我们可以用222个单调栈来维护当前的最大值序列,和最小值序列.

每次将rrr点加入左边所有的区间,从而形成新的区间,根据单调栈保存的信息,确定出哪些区间的最大值或者是最小值需要被修改,然后进行区间修改.

询问时候,直接查询[1,r][1,r][1,r]内最小值为000的个数,算贡献.

代码

#include <iostream>
#include <algorithm>
#include <cstring>
#define pr(x) std::cout << #x << ':' << x << std::endl
#define rep(i,a,b) for(int i = a;i <= b;++i)
#define clr(x) memset(x,0,sizeof(x))
#define setinf(x) memset(x,0x3f,sizeof(x))const int N = 300007,inf = 1e9;
int n,m;
typedef std::pair<int,int> pii;
int a[N];struct node{int val,cnt,tag,len;node(int val = 0,int cnt = 1,int tag = 0,int len = 1):val(val),cnt(cnt),tag(tag),len(len){}
}ns[N<<2];
//线段树维护的是区间最小值以及最小值的个数
inline void pushdown(int o) {if(ns[o].tag) {ns[o<<1].val += ns[o].tag;ns[o<<1|1].val += ns[o].tag;ns[o<<1].tag += ns[o].tag;ns[o<<1|1].tag += ns[o].tag;ns[o].tag = 0;}
}inline node maintain(node &lch,node &rch) {node res = node(std::min(lch.val,rch.val),0,0,lch.len+rch.len);if(lch.val == res.val) res.cnt += lch.cnt;if(rch.val == res.val) res.cnt += rch.cnt;return res;
}inline void change(int o,int l,int r,int cl,int cr,int val) {if(cl <= l && r <= cr) {ns[o].tag += val;ns[o].val += val;return ;}	if(r < cl || cr < l) return;int mid = (l + r) >> 1;pushdown(o);change(o<<1,l,mid,cl,cr,val);change(o<<1|1,mid+1,r,cl,cr,val);ns[o] = maintain(ns[o<<1],ns[o<<1|1]);
}inline node query(int o,int l,int r,int ql,int qr) {if(ql <= l && r <= qr) return ns[o];if(r < ql || qr < l)return node(inf,1,0,0);int mid = (l + r) >> 1;pushdown(o);node lch = query(o<<1,l,mid,ql,qr);node rch = query(o<<1|1,mid+1,r,ql,qr);return maintain(lch,rch);
}inline void build(int o,int l,int r) {if(l == r) {ns[o] = node(0,1,0,1);return ;}int mid = (l + r) >> 1;build(o<<1,l,mid);build(o<<1|1,mid+1,r);ns[o] = maintain(ns[o<<1],ns[o<<1|1]);
}pii mx[N],mi[N];
int topx,topi;int main() {std::cin >> n;build(1,1,n);rep(i,1,n) {int idx,y;std::cin >> idx >> y;a[idx] = y;}long long ans = 0;rep(i,1,n) {change(1,1,n,i,i,i);while(topx > 0 && mx[topx].first < a[i]) {change(1,1,n,mx[topx-1].second+1,mx[topx].second,a[i] - mx[topx].first);topx--;}mx[++topx] = (pii){a[i],i};while(topi > 0 && mi[topi].first > a[i]) {change(1,1,n,mi[topi-1].second+1,mi[topi].second,mi[topi].first - a[i]);topi--;}mi[++topi] = (pii){a[i],i};change(1,1,n,1,i,-i);node res = query(1,1,n,1,i);ans += res.cnt;change(1,1,n,1,i,i);}std::cout << ans << std::endl;return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/321077.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

P5664-Emiya家今天的饭【dp】

正题 题目链接:https://www.luogu.com.cn/problem/P5664 题目大意 对于nnn个方法&#xff0c;mmm个材料&#xff0c;一个方法配对一个材料可以做an,ma_{n,m}an,m​道菜。选择kkk个配对要求 配对至少为k>1k>1k>1每个配对的方法不同每个材料最多用⌊k2⌋\lfloor\frac…

GitHub宣布GitHub Education 新计划,学校可免费用企业版

今天 GitHub 宣布面向所有学校和教育机构开放 GitHub Education&#xff0c;方便学生和老师免费使用 GitHub 企业版功能&#xff0c;以及学生开发者工具包、GitHub 教室、培训等资源。2014 年&#xff0c;GitHub 推出了学生开发者工具包&#xff0c;其中包括 Azure 等云服务、G…

【dfs】聚会

聚会 题目大意&#xff1a; 有一些树&#xff0c;求深的树的深度 原题 解题思路&#xff1a; 从一个根出发&#xff0c;dfs往下搜 代码&#xff1a; #include<cstdio> #include<iostream> #include<cstring> using namespace std; int n,t,g,w,ans,c[2…

P3960-列队【权值线段树】

正题 题目链接:https://www.luogu.com.cn/problem/P3960 题目大意 n∗mn*mn∗m的队列&#xff0c;起初站在第(i,j)(i,j)(i,j)位置的人编号是(i−1)∗nj(i-1)*nj(i−1)∗nj。然后每次选择一个人出队后所有人向左补齐后所有人向前补齐&#xff0c;然后刚刚出列的那个人入队。 求…

2018 大湾区(深圳) .NET技术分享交流会 第一期

.NET Core 2.1 已于2018年5月30日正式发布&#xff0c;邀请粤港澳大湾区.NET技术专家和从业人员&#xff0c;一起分享与交流.NET技术的发展方向&#xff0c;提高粤港澳大湾区.NET技术交流氛围&#xff0c;挖掘.NET高级人才&#xff0c;为改善.NET生态系统贡献力量&#xff0c;使…

线段树-Mex-洛谷P4137

Mex 问题提出 有一个长度为nnn的数组{a1,a2,…,an}\{a_1,a_2,…,a_n\}{a1​,a2​,…,an​}。mmm次询问&#xff0c;每次询问一个区间内最小没有出现过的自然数。 题目解答 对1−n1-n1−n这里能够的每个数xxx,都统计出来在数组中出现的位置,并在前补上000,在后补上n1n1n1. …

卡车

卡车 题目大意&#xff1a; 有一个卡车向里面放东西&#xff08;重量要么是一要么是二&#xff09;&#xff0c;价值不同&#xff0c;放的东西的价值之和最大是多少 原题&#xff1a; 解题思路&#xff1a; 看看数据就知道DP会MLE&#xff0c;所以要用排序来做&#xff0c;…

P2831-愤怒的小鸟【状压dp】

正题 题目链接:https://www.luogu.com.cn/problem/P2831 题目大意 nnn个点&#xff0c;每次可以射掉在函数yax2bxyax^2bxyax2bx上的点&#xff08;a,ba,ba,b自定但是要求a<0a<0a<0&#xff09;。求最少射击次数。 解题思路 考虑状压&#xff0c;我们发现如果一次射掉…

初一级模拟赛总结(3.15)

成绩&#xff1a; rankrankranknamenamenamescorescorescoreT1T1T1T2T2T2T3T3T3T4T4T4111lyflyflyf220220220100100100100100100000202020222fyfyfy150150150000100100100000505050333lthlthlth120120120100100100202020000000444hkyhkyhky100100100000100100100000000444tjhtj…

从明面上学习ASP.NET Core

一、前言这篇文章就是从能看到地方去学习Core&#xff0c;没有很深奥&#xff0c;也没有很难懂&#xff0c;现在我们开始吧。二、构建项目&#xff0c;引发思考创建项目的步骤真的很简单&#xff0c;你要是不会&#xff0c;我真也没法了&#xff0c;我这是创建的MVC的项目。接下…

线段树-区间的交

区间的交 题目来源 孙耀峰Segment_Tree.pdf 原创 题目描述 给定nnn个区间,[li,ri][l_i,r_i][li​,ri​],可以选出其中一些区间,设选出tottottot个,令xxx表示这tottottot个区间交的长度.求min{x,tot}min\{x,tot\}min{x,tot}n≤105,1≤xi≤yi≤nn \le 10^5,1 \le x_i \le y_i…

【DP】收银员

收银员 题目大意&#xff1a; 有n件物品&#xff0c;每件物品有他的扫描时间和价格&#xff0c;在扫描的时候可以偷物品&#xff08;一个单位时间偷一件&#xff09;&#xff0c;问最少给多少钱 原题&#xff1a; 解题思路&#xff1a; 设f[j]为偷或买共j件花的最少钱&…

P5020-货币系统【背包】

正题 题目链接:https://www.luogu.com.cn/problem/P5020 题目大意 定义S(A)S(A)S(A)表示集合AAA内的若干个数字和&#xff08;可以重复使用&#xff09;可以表示的集合 nnn个数的集合FFF&#xff0c;求一个最小的集合G⊆FG\subseteq FG⊆F且S(F)S(G)S(F)S(G)S(F)S(G)。 解题思…

线段树-Chossing Ads-分治,主元素思想,神题

Choosing Ads 问题提出 给出长度为nnn的序列AAA,以及数ppp(20≤p≤10020\le p \le 10020≤p≤100)QQQ次操作,两种类型 (1,l,r)(1,l,r)(1,l,r),区间赋值为vvv(2,l,r)(2,l,r)(2,l,r),区间出现频率≥p%\ge p\%≥p%的数 n,Q≤105n,Q \le 10^5n,Q≤105 问题解答 非常巧妙的一道题…

P2679-子串【dp】

正题 题目链接:https://www.luogu.com.cn/problem/P2679 题目大意 长度为nnn的字符串AAA和长度为mmm的字符串BBB&#xff0c;要求从AAA中截取kkk个不重复的非空子串使得他们按顺序拼接起来是字符串BBB。求方案数。 解题思路 设fi,j,k,0/1f_{i,j,k,0/1}fi,j,k,0/1​表示AAA到…

【字符串】字符串

字符串 题目大意&#xff1a; 有一个字符串&#xff0c;问有子串“bear”的子串有多少个 原题&#xff1a; 题目描述 小熊有一个由小写英文字母组成的字符串s s1s2…sn。小熊想要计算s中有多少子串包含字符串“bear”&#xff0c;也就是找出满足字符串x(i, j) sisi1…sj …

.Net Core小技巧 - Swagger适配虚拟目录及二级目录

前言随着前后端分离模式与微服务架构的出现&#xff0c;Web API变得越来越重要及普遍。而后出现的网关技术&#xff0c;使开发者更倾向于使用二级/多级目录来暴露Web API&#xff0c;一是暴露的端口更少&#xff0c;方便管理&#xff1b;二是在网关中可以处理一些公共的事务&am…

线段树-Count on a Treap-神题

Count on a Treap 题目来源 Codechef Feb 2014 COT5 https://www.codechef.com/problems/COT5 问题提出 什么是Treap 是一颗二叉搜索树,每个节点拥有keykeykey属性.是一颗堆,每个节点拥有weightweightweight属性 问题 nnn次操作,三种类型,要求维护"大根Treap" …

P6834-[Cnoi2020]梦原【数学期望,树状数组】

正题 题目链接:https://www.luogu.com.cn/problem/P6834?contestId34123 题目大意 nnn个点&#xff0c;每个点i(i≠1)i(i\neq 1)i(i​1)随机连接[i−k,i−1][i-k,i-1][i−k,i−1]中的一个点。对于每个点有一个权值aia_iai​。每次可以选择一个全部都是正权值的连通块里所有…

好代码是管出来的——使用Git来管理源代码

软件开发过程中一个重要的产出就是代码&#xff0c;软件的编码过程一般是由一个团队共同完成&#xff0c;它是一个并行活动&#xff0c;为了保证代码在多人开发中能够顺利完成&#xff0c;我们需要使用代码版本控制工具来对代码进行统一存储&#xff0c;并追踪每一份代码的历史…