rt,思路是用 st 表,枚举左端点然后二分重合的部分,第一次二分第一次重合,第二次二分最后一次,相减即结果。
#include<bits/stdc++.h>
using namespace std;
int a[200010],b[200010];
int lg2[200010];
int st1[20][200010],st2[20][200010];
int query(int which,int l,int r)
{
int len=lg2[r-l+1];
if(which==1) return max(st1[len][l],st1[len][r-(1<<len)+1]);
else return min(st2[len][l],st2[len][r-(1<<len)+1]);
}
int main()
{
int n;
long long ans=0;
scanf("%d",&n);
for(int i=1; i<=n; ++i)
{
scanf("%d",&a[i]);
st1[0][i]=a[i];
}
for(int i=1; i<=n; ++i)
{
scanf("%d",&b[i]);
st2[0][i]=b[i];
}
for(int i=2; i<=n; ++i) lg2[i]=lg2[i>>1]+1;
for(int i=1; i<=18; ++i)
{
for(int j=1; j+(1<<i)-1<=n; ++j)
{
st1[i][j]=max(st1[i-1][j],st1[i-1][j+(1<<i-1)]);
st2[i][j]=min(st2[i-1][j],st2[i-1][j+(1<<i-1)]);
}
}
for(int i=1; i<=n; ++i)
{
int l=i,r=n,ans1=114514,ans2=-114514,mid;
while(l<=r)
{
mid=(l+r)>>1;
if(query(1,i,mid)>=query(2,i,mid))
{
r=mid-1;
ans1=mid;
}
else l=mid+1;
}
l=i,r=n;
while(l<=r)
{
mid=(l+r)>>1;
if(query(1,i,mid)<=query(2,i,mid))
{
l=mid+1;
ans2=mid;
}
else r=mid-1;
}
ans+=max(ans2-ans1+1,0);
}
printf("%lld",ans);
return 0;
}
本地对拍拍不出来 /kel