Friends and Subsequences CodeForces
阿新 • • 發佈:2018-12-11
分別對a和b維護最大和最小rmq 列舉左端點 右端點滿足單調性 二分找第一個和最後一個使a和b區間最值相等的點即為右端點
#include <bits/stdc++.h> using namespace std; #define ll long long int a[200010][20],b[200010][20]; int n; void init() { int i,j; for(j=1;(1<<j)<=n;j++) { for(i=1;i+(1<<j)-1<=n;i++) { a[i][j]=max(a[i][j-1],a[i+(1<<(j-1))][j-1]); } } for(j=1;(1<<j)<=n;j++) { for(i=1;i+(1<<j)-1<=n;i++) { b[i][j]=min(b[i][j-1],b[i+(1<<(j-1))][j-1]); } } return; } int query(int op,int l,int r) { int len; len=log2(double(r-l+1)); if(op==1) return max(a[l][len],a[r-(1<<len)+1][len]); else return min(b[l][len],b[r-(1<<len)+1][len]); } int main() { ll ans; int i,pl,pr,l,r,m,rl,rr; scanf("%d",&n); for(i=1;i<=n;i++) scanf("%d",&a[i][0]); for(i=1;i<=n;i++) scanf("%d",&b[i][0]); init(); ans=0; for(i=1;i<=n;i++) { pl=-1,l=i,r=n; while(l<=r) { m=(l+r)/2; rl=query(1,i,m); rr=query(2,i,m); if(rl<rr) l=m+1; else if(rl==rr) pl=m,r=m-1; else r=m-1; } pr=-1,l=i,r=n; while(l<=r) { m=(l+r)/2; rl=query(1,i,m); rr=query(2,i,m); if(rl<rr) l=m+1; else if(rl==rr) pr=m,l=m+1; else r=m-1; } if(pl!=-1) ans+=(pr-pl+1); } printf("%lld\n",ans); return 0; } /* 2 3 2 4 3 */