Codeforces 689D -Friends and Subsequences (RMQ查询-> ST表+二分)
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.
13
[题意]
给定两个 序列 A B, 问 在 区间[L,R]的区间内 A序列的最大值== B序列的最小值, 这样的区间有多少个.
[思路]
查询区间最值问题, 而且是 多次 查询, 用ST 表 提前预处理操作. 然后 二分 满足情况的A的左端点, B的右端点
两个端点之间 的区间都是 可以的, 所以答案就是 B.R-A.L +1
[代码实现]
//#include <bits/stdc++.h> #include <iostream> #include <stdio.h> #include <algorithm> #include <cmath> #include <math.h> #include <cstring> #include <string> #include <queue> #include <deque> #include <stack> #include <stdlib.h> #include <list> #include <map> #include <utility> #include <set> #include <bitset> #include <vector> #define mem(a,b) memset(a,b,sizeof(a)) #define findx(x,b,n) lower_bound(b+1,b+1+n,x)-b #define FIN freopen("input.txt","r",stdin) #define FOUT freopen("output.txt","w",stdout) #define SHUT ios_base::sync_with_stdio(false); cout.setf(ios::fixed); cout.precision(20); cout.tie(nullptr); cin.tie(nullptr); #define lson rt << 1, l, mid #define rson rt << 1|1, mid + 1, r #define FI(n) IO::read(n) #define Be IO::begin() using namespace std; typedef long long ll; const double PI=acos(-1); const int INF=0x3f3f3f3f; const double esp=1e-6; const int maxn=1e6+5; const int MAXN=50005; const int MOD=1e9+7; const int mod=1e9+7; int dir[5][2]={0,1,0,-1,1,0,-1,0}; namespace IO { const int MT = 5e7; char buf[MT]; int c,sz; void begin(){ c = 0; sz = fread(buf, 1, MT, stdin);//一次性输入 } template<class T> inline bool read(T &t){ while( c < sz && buf[c] != '-' && ( buf[c]<'0' || buf[c] >'9')) c++; if( c>=sz) return false; bool flag = 0; if( buf[c]== '-') flag = 1,c++; for( t=0; c<=sz && '0' <=buf[c] && buf[c] <= '9'; c++ ) t= t*10 + buf[c]-'0'; if(flag) t=-t; return true; } } int Max[maxn][20],Min[maxn][20]; void st(int l,int r) { int top=log((r-l+1)*1.0)/log(2.0); //for(int i-l;i<=r;i++) //Min[i][0]=Max[i][0]=a[i]; for(int j=1;j<=top;j++) for(int i=1;i+(1<<j)-1<=r;i++) { Max[i][j]=max(Max[i][j-1],Max[i+(1<<(j-1))][j-1]); Min[i][j]=min(Min[i][j-1],Min[i+(1<<(j-1))][j-1]); } } int query(int flag,int l,int r) { int x= (int)log2(r*1.0-l+1); if(flag) return max(Max[l][x],Max[r-(1<<x)+1][x]); return min(Min[l][x],Min[r-(1<<x)+1][x]); } int main() { int n; cin>>n; for(int i=1;i<=n;i++) cin>>Max[i][0]; for(int i=1;i<=n;i++) cin>>Min[i][0]; st(1,n); ll ans=0; int le,ri; for(int i=1;i<=n;i++) { le=i-1; ri=n+1; while(le+1<ri)// 二分左端点 { int mid= (le+ri)>>1; if(query(1,i,mid)-query(0,i,mid)<0) le=mid; else ri=mid; } if( ri>n) continue; int x=ri; le=i-1,ri=n+1; while(le+1<ri) { int mid=(le+ri)>>1; if(query(1,i,mid)-query(0,i,mid)>0) ri=mid; else le=mid; } le= min(le,n); //cout<<x<<" "<<le<<endl; if(le>=x) ans+= (le-x)+1; } cout<<ans<<endl; return 0; }