CodeForces 689D-Friends and Subsequences

来源:互联网 发布:小孩子学计算机编程 编辑:程序博客网 时间:2024/05/21 22:24

题目

D. Friends and Subsequences
time limit per test
2 seconds
memory limit per test
512 megabytes
input
standard input
output
standard output

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 andb of lengthn. 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 answer 3 to any query pair, but !Mike will always answer 1.

题意

给出长度为n的两个数组a,b,问有多少个区间,使这个a数组在区间上的最大值等于b数组在这个区间上的最小值。

解法

先对a,b两个数组做rmq,以便快速查询最大最小值,然后枚举左端点,二分右端点
对于每个左端点l,要么不存在一个右端点r,使a在[l,r]的最大值等于b在[l,r]上的最小值
如果存在,则可以二分出两个右端点r1,r2,使r1是离l最近的位置使a在[l,r1]上的最大值等于b在[l,r2]上的最小值,r2则是最远的位置,显然答案应该加上(r2-r1+1)。

代码

#include<cstdio>#define LL long longint a[200005],b[200005],maxa[200005][30],minb[200005][30];int max(int a,int b){return a>b?a:b;}int min(int a,int b){return a<b?a:b;}void pre(int n){int i,j;for(i=0;i<n;i++){maxa[i][0]=a[i];minb[i][0]=b[i];}for(j=1;(1<<j)<=n;j++)for(i=0;i+(1<<j)-1<n;i++){maxa[i][j]=max(maxa[i][j-1],maxa[i+(1<<(j-1))][j-1]);minb[i][j]=min(minb[i][j-1],minb[i+(1<<(j-1))][j-1]);}}int rmq(int l,int r,int ty)//ty是1表示询问a在[l,r]上的最大值,0则是询问b在[l,r]上的最小值{int k=0;while((1<<(k+1))<=r-l+1) k++;if(ty)return max(maxa[l][k],maxa[r-(1<<k)+1][k]);elsereturn min(minb[l][k],minb[r-(1<<k)+1][k]);}int main(){int n,i;scanf("%d",&n);for(i=0;i<n;i++)scanf("%d",&a[i]);for(i=0;i<n;i++)scanf("%d",&b[i]);pre(n);LL ans=0;for(i=0;i<n;i++){int l=i,r=n-1,mid,flag=0;//二分左端点while(l<=r){mid=(l+r)/2;int ma=rmq(i,mid,1);int mi=rmq(i,mid,0);if(ma==mi){flag=1;}if(ma>mi)r=mid-1;elsel=mid+1;}if(flag==0)//如果没有一个区间使最大值等于最小值,二分是无效的continue;int ans1=r;l=i,r=n-1;//二分右端点while(l<=r){mid=(l+r)/2;int ma=rmq(i,mid,1);int mi=rmq(i,mid,0);if(ma<mi)l=mid+1;elser=mid-1;}int ans2=l;if(flag)ans=ans+(LL)(ans1-ans2+1);}printf("%I64d\n",ans);return 0;}


0 0