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; }