codeforces Round #361 D. Friends and Subsequences (ST表,二分)

来源:互联网 发布:高通编译linux 编辑:程序博客网 时间:2024/05/01 14:28

D. Friends and Subsequences


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 exactlyn(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?

Input

The first line contains only integer n (1 ≤ n ≤ 200 000).

The second line contains n integer numbersa1, a2, ..., an ( - 109 ≤ ai ≤ 109) — the sequencea.

The third line contains n integer numbersb1, b2, ..., bn ( - 109 ≤ bi ≤ 109) — the sequenceb.

Output

Print the only integer number — the number of occasions the robot will count, thus for how many pairs is satisfied.

Examples
Input
61 2 3 2 1 46 7 1 2 3 2
Output
2
Input
33 3 31 1 1
Output
0
Note

The occasions in the first sample case are:

1.l = 4,r = 4 sincemax{2} = min{2}.

2.l = 4,r = 5 sincemax{2, 1} = min{2, 3}.

There are no occasions in the second sample case since Mike will answer3 to any query pair, but !Mike will always answer1.


           题意:查找两数组有区间最大与最小值相同的区间的个数。

          思路:其中一个序列是区间求最大,最大值递非递减的。另一个求最小值则相反,是非递增的。所以两者必然有一个相同的值 的区间。因此可以枚举起点,二分最大与最小相同的对应区间右断点的左界与右界,(右界 - 左界 +1 ) 就是以枚举的当前点为左端点,区间最大值与最小值相同的区间个数。在查找区间最大与最小时需要用st表来查找,一开始用线段树第七组数据就超时了。

         ST表其实也就是倍增思想。

详细见代码:

#include<iostream>#include<cstring>#include<cstdio>#include<cmath>#include<algorithm>#include<stack>#include<queue>using namespace std;#define INF 0x3f3f3f3f#define lson l,mid,rt<<1#define rson mid+1,r,rt<<1|1const int maxn =3* 1e5+100;typedef long long LL;int A[maxn][20];int B[maxn][20];int len[maxn];int n;void init(){len[1]=0;for(int i=2;i<maxn;i++){len[i]=len[i-1];if((1<<(len[i]+1)) == i) len[i]++;}}void work(int &n){int i,j;for(i=n;i>=1;i--){for(j=1;(i+(1<<j)-1) <=n;j++){A[i][j]=max(A[i][j-1],A[i+(1<<(j-1))][j-1]);B[i][j]=min(B[i][j-1],B[i+(1<<(j-1))][j-1]);}}}inline int query1(int &l,int &r){return max(A[l][len[r-l+1]],A[r-(1<<len[r-l+1])+1][len[r-l+1]]);}inline int query2(int &l,int &r){return min(B[l][len[r-l+1]],B[r-(1<<len[r-l+1])+1][len[r-l+1]]);}int main(){init();int n;int i,j;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]);work(n);LL ans=0;for(i=1;i<=n;i++){int lo=i-1;int ub=n+1;int mid;while(ub-lo>1){mid=(lo+ub)>>1;if(query1(i,mid)-query2(i,mid)<0)lo=mid;else ub=mid;}if(ub>n) continue;int a=ub;lo=i-1;ub=n+1;while(ub-lo>1){mid=(lo+ub)>>1;if(query1(i,mid)-query2(i,mid)>0)ub=mid;else lo=mid;}//cout<<lo<<" "<<a<<endl;lo=min(lo,n);if(lo>=a)ans=ans+lo-a+1;}cout<<ans<<endl;return 0;}


0 0
原创粉丝点击