码迷,mamicode.com
首页 > 其他好文 > 详细

Friends and Subsequences - 二分 + ST表

时间:2020-06-27 19:49:33      阅读:59      评论:0      收藏:0      [点我收藏+]

标签:时间   query   set   lse   个数   stream   序列   end   tps   

传送门
很棒的题。
有两个序列a和b,长度都为n,对于a序列需要知道区间的最大值,对于b序列需要知道区间的最小值
求出符合式子
\(max_{i = l}^ra_i = min_{i = l}^rb_i\)
的所有区间个数。

方法很简单,用st表分别维护a序列的最大值的b序列的最小值,明显,a序列的st表是一个递增函数,b序列的st表是一个递减函数
令a序列的st表减去b序列的st表,那么这个值也是递增的,如果说,值是0,那么久满足题目的情况。
那么遍历左区间,进行二分,用st表\(O(1)\)查询找到0最后一次出现的位置和第一次出现的位置,那么答案就是[左区间, 右区间2 - 右区间1 + 1],都是满足情况的
时间复杂度\(O(nlogn)\)

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#define ll long long
using namespace std;
const int N = 2e5 + 5;
int a[N], b[N], n, k;
int MAX[N][20], MIN[N][20];
void init(){
    memset(MIN, 0x3f, sizeof(MIN));
    memset(MAX, 0, sizeof(MAX));
    for(int i = 1; i <= n; i++){
        MAX[i][0] = a[i];
        MIN[i][0] = b[i];
    }

    for(int j = 1; j <= 20; j++)
        for(int i = 1; i + (1 << j) - 1 <= n; i++){
            MIN[i][j] = min(MIN[i][j - 1], MIN[i + (1 << (j - 1))][j - 1]);
            MAX[i][j] = max(MAX[i][j - 1], MAX[i + (1 << (j - 1))][j - 1]);
        }
}
int Query(int l, int r){
    int k = log2(r - l + 1);
    return max(MAX[l][k], MAX[r - (1 << k) + 1][k]) - min(MIN[l][k], MIN[r - (1 << k) + 1][k]);
}
void solve(){
    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]);
    ll ans = 0;
    init();
    for(int i = 1; i <= n; i++){
        int l = i, r = n, mid;
        while(l <= r){
            mid = (l + r) >> 1;
            int now = Query(i, mid);
            if(now > 0) r = mid - 1;
            else l = mid + 1;
        }
        ans += r - i + 1;//[i, r] 都是 ≤ 0的
        l = i, r = n;
        while(l <= r){
            mid = (l + r) >> 1;
            int now = Query(i, mid);
            if(now < 0) l = mid + 1;
            else r = mid - 1;
        }
        ans -= r - i + 1;//[i, r] 都是 ≥ 0的
    }
    printf("%lld\n", ans);
}
int main(){
    solve();
    return 0;
}

Friends and Subsequences - 二分 + ST表

标签:时间   query   set   lse   个数   stream   序列   end   tps   

原文地址:https://www.cnblogs.com/Emcikem/p/13199252.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!