• 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;
    }
    
    
    
  • 相关阅读:
    5.3公理系统
    5.2逻辑语言vs逻辑演算
    Spike-in 对照(Spike-in control)
    R 语言学习笔记(4)—— 数值&字符处理
    R 语言学习笔记(3)—— 基础绘图
    R语言学习笔记(2)——数据结构与数据集
    R 语言学习笔记(1)——R 工作空间与输入输出
    单核苷酸多态性SNP(single nucleotide polymorphism)
    你真的遵守编码规范了吗
    论牧羊犬如何混迹于Scrum圈
  • 原文地址:https://www.cnblogs.com/Sunshine-tcf/p/5693342.html
Copyright © 2020-2023  润新知