Codeforces 689D -Friends and Subsequences (RMQ查询-> ST表+二分)

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.


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;
}


posted @ 2018-01-31 14:49  Sizaif  阅读(135)  评论(0编辑  收藏  举报