• 2019牛客多校第一场 A.Equivalent Prefixes


    A.Equivalent Prefixes

    传送门:https://ac.nowcoder.com/acm/contest/881/A

    题意:给你两个序列 A、B,两个区间相等的条件是区间内任意一个子区间的当前子区间的最小值的坐标相等,问你两个序列的1~p区间相等,求最大的p是多少

    题解:二分+分治+rmq

    因为区间p的取值不好取,于是我们二分答案

    check怎么check,因为我们的区间内每一个子区间都需要检查到,那么我们就需要从大区间检查到小区间,所以,很容易想到分治,递归到子区间去,再进行检查,检查的时候去找到区间最小值,为了检查的时候时间复杂度尽可能的小,我们需要需要用一种数据结构去得到区间最小值,这里使用了rmq预处理 O1查询

    代码

    #include <set>
    #include <map>
    #include <cmath>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    typedef long long LL;
    typedef pair<int, int> pii;
    typedef unsigned long long uLL;
    #define ls rt<<1
    #define rs rt<<1|1
    #define lson l,mid,rt<<1
    #define rson mid+1,r,rt<<1|1
    #define bug printf("*********
    ")
    #define FIN freopen("input.txt","r",stdin);
    #define FON freopen("output.txt","w+",stdout);
    #define IO ios::sync_with_stdio(false),cin.tie(0)
    #define debug1(x) cout<<"["<<#x<<" "<<(x)<<"]
    "
    #define debug2(x,y) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<"]
    "
    #define debug3(x,y,z) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<" "<<#z<<" "<<z<<"]
    "
    const int maxn = 100000 + 5;
    const int INF = 0x3f3f3f3f;
    int a[maxn], b[maxn];
    int pos1[maxn], pos2[maxn];
    int st1[maxn][20];
    int n;
    
    void rmq_init1() {
        for (int i = 1; i <= n; i++) {
            st1[i][0] = a[i];
        }
        int l = 2;
        for (int i = 1; l <= n; i++) {
            for (int j = 1; j + l / 2 <= n; j++) {
                st1[j][i] = min(st1[j][i - 1], st1[j + l / 2][i - 1]);
            }
            l <<= 1;
        }
    }
    int ask_min1(int i, int j) {
        int k = int(log(j - i + 1.0) / log(2.0));
        return min(st1[i][k], st1[j - (1 << k) + 1][k]);
    }
    
    int st2[maxn][20];
    
    void rmq_init2() {
        for (int i = 1; i <= n; i++) {
            st2[i][0] = b[i];
        }
        int l = 2;
        for (int i = 1; l <= n; i++) {
            for (int j = 1; j + l / 2 <= n; j++) {
                st2[j][i] = min(st2[j][i - 1], st2[j + l / 2][i - 1]);
            }
            l <<= 1;
        }
    }
    int ask_min2(int i, int j) {
        int k = int(log(j - i + 1.0) / log(2.0));
        return min(st2[i][k], st2[j - (1 << k) + 1][k]);
    }
    bool check(int l, int r) {
        if(l >= r) return true;
        int min1 = ask_min1(l, r);
        int min2 = ask_min2(l, r);
        int p1 = pos1[min1];
        int p2 = pos2[min2];
        if(p1 == p2) {
            return check(l, p1 - 1) && check(p1 + 1, r);
        } else {
            return false;
        }
    }
    int main() {
    
        while(scanf("%d", &n) != EOF) {
            for(int i = 1; i <= n; i++) {
                scanf("%d", &a[i]);
                pos1[a[i]] = i;
            }
            for(int i = 1; i <= n; i++) {
                scanf("%d", &b[i]);
                pos2[b[i]] = i;
            }
            rmq_init1();
            rmq_init2();
            int l = 1, r = n;
            int ans = 1;
            while(l <= r) {
                int mid = (l + r) >> 1;
                if(check(1, mid)) {
                    ans = mid;
                    l = mid + 1;
                } else {
                    r = mid - 1;
                }
            }
            printf("%d
    ", ans);
        }
        return 0;
    }
    
    每一个不曾刷题的日子 都是对生命的辜负 从弱小到强大,需要一段时间的沉淀,就是现在了 ~buerdepepeqi
  • 相关阅读:
    B
    A
    P1057 传球游戏
    P1702 突击考试
    P1394 山上的国度
    P2117 小Z的矩阵
    P1510 精卫填海
    P1294 高手去散步
    P1071 潜伏者
    保留
  • 原文地址:https://www.cnblogs.com/buerdepepeqi/p/11219836.html
Copyright © 2020-2023  润新知