题意
求连续段数。
n<=3e5
思路
- 析合树板题(然而并不会)
- 考虑分治求。
- 讨论max与min在左右两边的四种情况就行了。
#include <bits/stdc++.h>
using namespace std;
const int N = 3e5 + 10, Z = 3e5 * 2;
typedef long long ll;
int a[N], n;
int cnt[4 * N];
ll ans;
int b[N], no[N], len;
int smx[N], smi[N], pmx[N], pmi[N], omx[N], omi[N];
void divide(int L, int R) {
if (L == R) ans++;
if (L >= R) return;
int mid = L + R >> 1;
smx[mid + 1] = 0, smi[mid + 1] = n + 1;
pmx[mid] = 0, pmi[mid] = n + 1;
for(int i = mid + 1; i <= R; i++) {
pmx[i] = max(pmx[i - 1], a[i]);
pmi[i] = min(pmi[i - 1], a[i]);
}
for(int i = mid; i >= L; i--) {
smx[i] = max(smx[i + 1], a[i]);
smi[i] = min(smi[i + 1], a[i]);
}
int mi = mid, mx = mid;
omx[mid] = omi[mid] = mid;
for(int i = mid + 1; i <= R; i++) {
while(mx >= L && smx[mx] <= pmx[i]) mx--;
while(mi >= L && smi[mi] >= pmi[i]) mi--;
omx[i] = mx, omi[i] = mi;
}
ll zs = 0;
//part1
for(int i = mid + 1; i <= R; i++) {
int loc = i + pmi[i] - pmx[i];
if (omi[i] < loc && omx[i] < loc && loc <= mid) zs++;
}
//part2
for(int i = mid + 1; i <= R; i++) cnt[Z + i - pmx[i]] = 0;
for(int i = mid + 1; i <= R; i++) {
for(int j = omx[i - 1]; j > omx[i]; j--)
cnt[Z + j - smi[j]] ++;
for(int j = omi[i - 1]; j > omi[i]; j--)
cnt[Z + j - smi[j]] --;
if (omx[i] < omi[i]) zs += cnt[Z + i - pmx[i]];
}
//part3
for(int i = mid + 1; i <= R; i++) cnt[Z + i + pmi[i]] = 0;
for(int i = mid + 1; i <= R; i++) {
for(int j = omx[i - 1]; j > omx[i]; j--)
cnt[Z + j + smx[j]] --;
for(int j = omi[i - 1]; j > omi[i]; j--)
cnt[Z + j + smx[j]] ++;
if (omi[i] < omx[i]) zs += cnt[Z + i + pmi[i]];
}
//part4
for(int i = mid + 1; i <= R; i++) cnt[Z + i] = 0;
for(int i = L; i <= mid; i++) cnt[Z + smx[i] - smi[i] + i] ++;
int zq = mid;
for(int i = mid + 1; i <= R; i++) {
while(zq > omx[i]){
cnt[Z + smx[zq] - smi[zq] + zq] --;
zq--;
}
while(zq > omi[i]) {
cnt[Z + smx[zq] - smi[zq] + zq] --;
zq--;
}
zs += cnt[Z + i];
}
ans += zs;
divide(L, mid), divide(mid + 1, R);
}
int main() {
freopen("f.in", "r", stdin);
cin>>n; for(int i = 1; i <= n; i++) {
int x,y;scanf("%d %d",&x,&y);
a[x] = y;
}
divide(1, n);
cout<<ans<<endl;
}