zoukankan      html  css  js  c++  java
  • CodeForces 689D Friends and Subsequences (RMQ+二分)

    Friends and Subsequences

    题目链接:

    http://acm.hust.edu.cn/vjudge/contest/121333#problem/H

    Description

    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 max(alar)==min(blbr) is satisfied.

    Sample Input

    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

    Hint

    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数组任意区间的最大值、最小值;
    求有多少区间[l,r]满足max(alar)==min(blbr);

    题解:

    RMQ:O(nlgn)预处理 O(1)求出任意区间的min/max;

    在固定区间左端点情况下:
    由于最大值最小值均具有单调性;
    用两次二分操作分别求出第一次和最后一次满足min==max的右端点,作差累加即可;
    注意:两次二分操作的差别和意义.

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <queue>
    #include <map>
    #include <set>
    #include <vector>
    #define LL long long
    #define eps 1e-8
    #define maxn 201000
    #define mod 1000000007
    #define inf 0x3f3f3f3f
    #define IN freopen("in.txt","r",stdin);
    using namespace std;
    
    int n, A[maxn], B[maxn];
    int d_min[maxn][30];
    int d_max[maxn][30];
    
    void RMQ_init() {
        for(int i=0; i<n; i++) d_max[i][0] = A[i], d_min[i][0] = B[i];
        for(int j=1; (1<<j)<=n; j++)
            for(int i=0; i+(1<<j)-1<n; i++) {
                d_min[i][j] = min(d_min[i][j-1], d_min[i+(1<<(j-1))][j-1]);
                d_max[i][j] = max(d_max[i][j-1], d_max[i+(1<<(j-1))][j-1]);
            }
    }
    int RMQ_min(int L, int R) {
        int k = 0;
        while((1<<(k+1)) <= R-L+1) k++;
        return min(d_min[L][k], d_min[R-(1<<k)+1][k]);
    }
    int RMQ_max(int L, int R) {
        int k = 0;
        while((1<<(k+1)) <= R-L+1) k++;
        return max(d_max[L][k], d_max[R-(1<<k)+1][k]);
    }
    
    int main(int argc, char const *argv[])
    {
        //IN;
    
        while(scanf("%d",&n) != EOF)
        {
            for(int i=0; i<n; i++) scanf("%d",&A[i]);
            for(int i=0; i<n; i++) scanf("%d",&B[i]);
            RMQ_init();
    
            LL ans = 0;
            for(int i=0; i<n; i++) {
                if(A[i] > B[i]) continue;
                int first_r=-1, last_r=-1;
                int l=i,r=n-1,mid;
    
                while(l <= r) {
                    mid = (l+r) / 2;
                    if(RMQ_max(i,mid) == RMQ_min(i,mid)) first_r = mid;
                    if(RMQ_max(i,mid) >= RMQ_min(i,mid)) r = mid-1;
                    else l = mid+1;
                }
                if(first_r == -1) continue;
    
                l=i; r=n-1;
                while(l <= r) {
                    mid = (l+r) / 2;
                    if(RMQ_max(i,mid) > RMQ_min(i,mid))
                        r = mid-1;
                    else l = mid+1, last_r = mid;
                }
    
                ans += last_r - first_r + 1;
            }
    
            printf("%I64d
    ", ans);
        }
    
        return 0;
    }
    
    
    
  • 相关阅读:
    numpy 基础 —— np.linalg
    图像旋转后显示不完全
    opencv ---getRotationMatrix2D函数
    PS1--cannot be loaded because the execution of scripts is disabled on this system
    打开jnlp Faild to validate certificate, the application will not be executed.
    BATCH(BAT批处理命令语法)
    oracle vm virtualbox 如何让虚拟机可以上网
    merge 实现
    Windows batch,echo到文件不成功,只打印出ECHO is on.
    python2.7.6 , setuptools pip install, 报错:UnicodeDecodeError:'ascii' codec can't decode byte
  • 原文地址:https://www.cnblogs.com/Sunshine-tcf/p/5693342.html
Copyright © 2011-2022 走看看