Mike and !Mike are old childhood rivals, they are opposite in everything they do, except programming. Today they have a problem they cannot solve on their own, but together (with you) — who knows?
Every one of them has an integer sequences a and b of length n. Being given a query of the form of pair of integers (l, r), Mike can instantly tell the value of while !Mike can instantly tell the value of
.
Now suppose a robot (you!) asks them all possible different queries of pairs of integers (l, r)(1 ≤ l ≤ r ≤ n) (so he will make exactly n(n + 1) / 2 queries) and counts how many times their answers coincide, thus for how many pairs is satisfied.
How many occasions will the robot count?
The first line contains only integer n (1 ≤ n ≤ 200 000).
The second line contains n integer numbers a1, a2, ..., an ( - 109 ≤ ai ≤ 109) — the sequence a.
The third line contains n integer numbers b1, b2, ..., bn ( - 109 ≤ bi ≤ 109) — the sequence b.
Print the only integer number — the number of occasions the robot will count, thus for how many pairs is satisfied.
6 1 2 3 2 1 4 6 7 1 2 3 2
2
3 3 3 3 1 1 1
0
The occasions in the first sample case are:
1.l = 4,r = 4 since max{2} = min{2}.
2.l = 4,r = 5 since max{2, 1} = min{2, 3}.
There are no occasions in the second sample case since Mike will answer 3 to any query pair, but !Mike will always answer 1.
区间最值问题,要求A数列最大值和B数列最小值相等的区间个数。可以用RMQ处理,得到区间最值,对于区间最值,满足[l,r]<=[l,r+1],由单调性考虑用二分查找满足条件的最大(rmax)和最小(rmin)右端点,答案就是rmax-rmin+1;枚举左端点即可,时间复杂度O(n*log(n))。
#include<bits/stdc++.h>
using namespace std;
#define LL long long int
#define rep(i,a,n) for(int i=a;i<n;++i)
#define per(i,a,n) for(int i=n-1;i>=a;--i)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define mem(a,t) memset(a,t,sizeof(a))
#define all(v) v.begin(),v.end()
#define N 200005
const int inf=1e9+10;
int dpa[N][20];
int dpb[N][20];
int lg[N];
void rmq(int n){
rep(j,1,20){
for(int i=1;i+(1<<(j-1))<=n;++i){
dpa[i][j]=max(dpa[i][j-1],dpa[i+(1<<(j-1))][j-1]);
dpb[i][j]=min(dpb[i][j-1],dpb[i+(1<<(j-1))][j-1]);
}
}
}
int rmqmax(int l,int r){
int k=lg[r-l+1];
return max(dpa[l][k],dpa[r-(1<<k)+1][k]);
}
int rmqmin(int l,int r){
int k=lg[r-l+1];
return min(dpb[l][k],dpb[r-(1<<k)+1][k]);
}
int main()
{
int n;
scanf("%d",&n);
rep(i,1,n+1) scanf("%d",&dpa[i][0]);
rep(i,1,n+1) scanf("%d",&dpb[i][0]);
rep(i,2,n+1) lg[i]=lg[i>>1]+1; //lg[]数组满足:(1<<lg[i])<=i;
rmq(n);
LL ans=0;
int ans1,ans2,low,high,mid;
rep(i,1,n+1){
low=i;
high=n;
ans1=i-1; //ans1为满足相等条件往左一个位置下标
while(low<=high){
mid=(low+high)>>1;
if(rmqmax(i,mid)<rmqmin(i,mid)){
ans1=mid; //mid满足if条件,不相等且小于等号位置
low=mid+1;
}
else{
high=mid-1;
}
}
low=i;
high=n;
ans2=n+1; //ans2为满足相等条件往右一个位置下标
while(low<=high){
mid=(low+high)>>1;
if(rmqmax(i,mid)>rmqmin(i,mid)){
ans2=mid; //mid满足不相等条件,且大于等号位置
high=mid-1;
}
else{
low=mid+1;
}
}
ans+=ans2-ans1-1;
}
cout<<ans<<endl;
return 0;
}