Codeforces 689D. Friends and Subsequences(二分/尺取 + ST表)

来源:互联网 发布:免费手机数据恢复 编辑:程序博客网 时间:2024/05/01 09:33

题目链接

简单题意

给出两个序列a,b,问有几个区间满足,a[l,r]的最大值等于b[l,r]的最小值。

思路

用ST表来完成RMQ的询问,再用类似尺取的办法来扫一遍区间,但是这里有三个指针,一个是枚举的左端点,另外两个是得到使max和min相等的区间的左右端点。

当然也可以用二分来做,还是枚举左端点,得到使max和min相等的区间的左右端点。

代码

#include <cstdio>#include <algorithm>const int maxn = 2e5+10;using namespace std;int n;long long ans;int a[maxn][22], b[maxn][22];int getmax(int l, int r){    int k = 31 - __builtin_clz(r-l+1);    return max(a[l][k], a[r-(1<<k)+1][k]);}int getmin(int l, int r){    int k = 31 - __builtin_clz(r-l+1);    return min(b[l][k], b[r-(1<<k)+1][k]);}int main(){    scanf("%d" ,&n);    for(int i=0; i<n; i++)        scanf("%d" ,a[i]);    for(int i=0; i<n; i++)        scanf("%d" ,b[i]);    for(int j=0; j<20; j++)        for(int i=0; i+(1<<j)<n; i++){            a[i][j+1] = max(a[i][j], a[i+(1<<j)][j]);            b[i][j+1] = min(b[i][j], b[i+(1<<j)][j]);        }    int l=n-1, r=n;    for(int i=n-1; i>=0; i--){        while(r-1>=i && getmax(i,r-1) > getmin(i,r-1))  r--;        while(l>=i && getmax(i,l) >= getmin(i,l))       l--;        ans += max(0, r-l-1);    }    printf("%I64d" ,ans);}
0 0
原创粉丝点击