题目链接:Codeforces - Friends and Subsequences
很显然max和min的前缀和具有单调性。
所以我们枚举左端点,二分右端点即可。
AC代码:
#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N=2e5+10;
int n,a[N],b[N]; long long res;
int mx[N<<2],mi[N<<2];
void build(int p,int l,int r){
if(l==r){mx[p]=a[l],mi[p]=b[l]; return;}
int mid=l+r>>1;
build(p<<1,l,mid); build(p<<1|1,mid+1,r);
mx[p]=max(mx[p<<1],mx[p<<1|1]);
mi[p]=min(mi[p<<1],mi[p<<1|1]);
}
int askmax(int p,int l,int r,int ql,int qr){
if(l==ql&&r==qr) return mx[p];
int mid=l+r>>1;
if(qr<=mid) return askmax(p<<1,l,mid,ql,qr);
else if(ql>mid) return askmax(p<<1|1,mid+1,r,ql,qr);
else return max(askmax(p<<1,l,mid,ql,mid),askmax(p<<1|1,mid+1,r,mid+1,qr));
}
int askmin(int p,int l,int r,int ql,int qr){
if(l==ql&&r==qr) return mi[p];
int mid=l+r>>1;
if(qr<=mid) return askmin(p<<1,l,mid,ql,qr);
else if(ql>mid) return askmin(p<<1|1,mid+1,r,ql,qr);
else return min(askmin(p<<1,l,mid,ql,mid),askmin(p<<1|1,mid+1,r,mid+1,qr));
}
signed main(){
cin>>n;
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
for(int i=1;i<=n;i++) scanf("%d",&b[i]);
build(1,1,n);
for(int i=1;i<=n;i++){
int x0,x1; int l=i,r=n;
while(l<r){
int mid=l+r>>1;
if(askmax(1,1,n,i,mid)>=askmin(1,1,n,i,mid)) r=mid;
else l=mid+1;
}
x0=r;
if(askmax(1,1,n,i,x0)>askmin(1,1,n,i,x0)) continue;
l=x0,r=n;
if(askmax(1,1,n,i,n)==askmin(1,1,n,i,n)) x1=n;
else{
while(l<r){
int mid=l+r>>1;
if(askmax(1,1,n,i,mid)>askmin(1,1,n,i,mid)) r=mid;
else l=mid+1;
}
x1=r-1;
}
res+=(x1-x0+1);
}
cout<<res;
return 0;
}
青烟绕指柔!
发布了506 篇原创文章 · 获赞 241 · 访问量 3万+
私信
关注