CodeForces 689D-Friends and Subsequences

来源:互联网 发布:wacc的算法 编辑:程序博客网 时间:2024/05/22 05:20

题目链接:http://codeforces.com/contest/689/problem/D


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 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?
Input

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


题目大意:

给两个数列a,b,找这样的区间的个数:max{a[L…R]}=min{b[L..R]}


题解:

可以发现L固定,max{a[L..R]}随R递增,min{b[L..R]}随R递减,要他们相等,则要求他们有交集,由单调性,可以二分R,找到满足条件的第一个坐标R1,再找满足条件的最后一个坐标R2。判断函数用RMQ以O(1)的复杂度得到区间最值。则对此L,满足的区间数为R2-R1+1个,再枚举L,即可得到答案,时间复杂度O(n*log(n)).


AC代码:

#include <cstdio>#include <cmath>#include <cstdlib>#include <queue>#include <deque>#include <vector>#include <iostream>#include <cstring>#include <algorithm>#include <string>#include <cstring>#include <map>#include <set>#define pb push_back#define pf push_front#define IN insert#define ER erase#define sz size#define rbg rbegin()#define PB pop_back()#define fron front()#define emp empty()#define LL long longusing namespace std;const int N=200010;int ra[N][20],rb[N][20];int a[N],b[N],n;void initrmq(int n){    for(int i=1;i<=n;i++)        ra[i][0]=a[i],rb[i][0]=b[i];    for(int i=1;1<<i<=n;i++)    {        for(int j=1;j+(1<<i)-1<=n;j++)        {            ra[j][i]=max(ra[j][i-1],ra[j+(1<<(i-1))][i-1]);            rb[j][i]=min(rb[j][i-1],rb[j+(1<<(i-1))][i-1]);        }    }}int query(int l,int r,bool ty){    int k=0;    while((1<<(k+1))<=r-l+1) k++;    if(ty==0)        return max(ra[l][k],ra[r-(1<<k)+1][k]);    else        return min(rb[l][k],rb[r-(1<<k)+1][k]);}int main(){    long long ans=0;    scanf("%d",&n);    for(int i=1;i<=n;i++)        scanf("%d",&a[i]);    for(int i=1;i<=n;i++)        scanf("%d",&b[i]);    initrmq(n);    for(int i=1;i<=n;i++)    {        int l=i,r=n,mid;        bool flag=0;        while(l<=r)        {            mid=(l+r)/2;            int maxa=query(i,mid,0),minb=query(i,mid,1);            if(maxa==minb)            {                flag=1;            }            if(maxa>minb)                r=mid-1;            else                l=mid+1;        }        if(flag)        {            int ar=r,al;            l=i;r=n;mid=(l+r)/2;            while(l<=r)            {                mid=(l+r)/2;                int maxa=query(i,mid,0),minb=query(i,mid,1);                if(maxa<minb)                    l=mid+1;                else                    r=mid-1;            }            al=l;            ans=ans+ar-al+1;        }    }    printf("%I64d",ans);    return 0;}
0 0
原创粉丝点击