題目鏈接:https://codeforces.com/problemset/problem/689/D
題意:有多少區間[l, r]滿足,max(al..ar) = min(bl..br)
題解:對於先固定l,那麼對於max(a),是一個遞增的序列,對於min(b)是一個遞減的序列,因此我們就可以二分確定出,第一個符合條件的位置和最後一個符合條件的位置
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 200100;
int a[N], b[N];
int dp1[N][22], dp2[N][22];
int n;
int getmax(int l, int r) {
int k = log2(r - l + 1);
return max(dp1[l][k], dp1[r - (1 << k) + 1][k]);
}
int getmin(int l, int r) {
int k = log2(r - l + 1);
return min(dp2[l][k], dp2[r - (1 << k) + 1][k]);
}
int low(int pos) {
int ans = -1;
int cnt1, cnt2;
int l = pos, r = n, mid;
while(l <= r) {
mid = (l + r) >> 1;
cnt1 = getmax(pos, mid);
cnt2 = getmin(pos, mid);
if(cnt1 > cnt2) r = mid - 1;
else if(cnt1 < cnt2) l = mid + 1;
else {
ans = mid;
r = mid - 1;
}
}
return ans;
}
int upp(int pos) {
int ans = -1;
int cnt1, cnt2;
int l = pos, r = n, mid;
while(l <= r) {
mid = (l + r) >> 1;
cnt1 = getmax(pos, mid);
cnt2 = getmin(pos, mid);
if(cnt1 > cnt2) r = mid - 1;
else if(cnt1 < cnt2) l = mid + 1;
else {
ans = mid;
l = mid + 1;
}
}
if(ans == -1) return -2;
else return ans;
}
int main() {
ll ans = 0;
scanf("%d", &n);
for(int i = 1; i <= n; i++) scanf("%d", &a[i]), dp1[i][0] = a[i];
for(int i = 1; i <= n; i++) scanf("%d", &b[i]), dp2[i][0] = b[i];
for(int i = 1; i < 22; i++)
for(int j = 1; j + (1 << i) - 1 <= n; j++)
dp1[j][i] = max(dp1[j][i - 1], dp1[j + (1 << (i - 1))][i - 1]);
for(int i = 1; i < 22; i++)
for(int j = 1; j + (1 << i) - 1 <= n; j++)
dp2[j][i] = min(dp2[j][i - 1], dp2[j + (1 << (i - 1))][i - 1]);
for(int i = 1; i <= n; i++) {
ans += upp(i) - low(i) + 1;
}
cout << ans << endl;
return 0;
}