CF1849E Max to the Right of Min 题解
KingPowers · · 题解
题目链接
这里是线段树题解,其实是个套路题。
类似扫描线的思想,我们可以枚举右端点
我们记
如果
如果
事实上,因为
当
时间复杂度:
int n,p[N],mx[N],mn[N];
int top,st[N];
namespace DS{
#define ls(now) now<<1
#define rs(now) now<<1|1
int sum[N<<2],tag[N<<2];
void pushup(int now){
sum[now]=sum[ls(now)]+sum[rs(now)];
}
void cov(int l,int r,int now,int c){
sum[now]=(r-l+1)*c;tag[now]=c;
}
void pushdown(int l,int r,int now){
if(tag[now]==-1) return;
int mid=(l+r)>>1;
cov(l,mid,ls(now),tag[now]);
cov(mid+1,r,rs(now),tag[now]);
tag[now]=-1;
}
void modify(int x,int y,int c,int l,int r,int now){
if(x<=l&&r<=y) return cov(l,r,now,c);
pushdown(l,r,now);
int mid=(l+r)>>1;
if(x<=mid) modify(x,y,c,l,mid,ls(now));
if(y>mid) modify(x,y,c,mid+1,r,rs(now));
pushup(now);
}
}
void Main(){
cin>>n;
For(i,1,n) cin>>p[i];
st[top=1]=n;
Rof(i,n-1,1){
while(top&&p[st[top]]<p[i]) mx[st[top--]]=i;
st[++top]=i;
}
st[top=1]=n;
Rof(i,n-1,1){
while(top&&p[st[top]]>p[i]) mn[st[top--]]=i;
st[++top]=i;
}
ll ans=0;
For(i,2,n){
if(mx[i]!=i-1) DS::modify(mx[i]+1,i-1,1,1,n,1);
if(mn[i]!=i-1) DS::modify(mn[i]+1,i-1,0,1,n,1);
ans+=DS::sum[1];
}
cout<<ans<<'\n';
}