您的位置:首页 > 产品设计 > UI/UE

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

2016-07-07 21:39 447 查看

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 sequence
a.

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

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


is satisfied.

Examples

Input
6
1 2 3 2 1 4
6 7 1 2 3 2


Output
2


Input
3
3 3 3
1 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 answer
1.

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

          思路:其中一个序列是区间求最大,最大值递非递减的。另一个求最小值则相反,是非递增的。所以两者必然有一个相同的值 的区间。因此可以枚举起点,二分最大与最小相同的对应区间右断点的左界与右界,(右界 - 左界 +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|1
const 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  codeforces 二分 st表