题解 | #Away from College#

Away from College

https://ac.nowcoder.com/acm/contest/11256/A

K King of Range

1.方法:st表加双指针

2.题意

给你一个长为n的数组,有m次询问,每次询问给你一个k,问有多少对(l,r),使数组区间l到r的最大值与最小值的差大于k

3.思路

若给你个子数组发现最大值与最小值的差已经满足条件,那么是不是意味着在这个子数组的基础上在添加其他的元素,其最大值与最小值的差也会成立。所以我们可以用双子针,固定i的位置,来找最小的j。要在一个区间内找最小值,我们可以用st表。

4.代码如下

#include <bits/stdc++.h>
using namespace std;
#define js ios::sync_with_stdio(false);cin.tie(0); cout.tie(0)
typedef long long ll; typedef unsigned long long ull; typedef long double ld;
inline ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : x; }
ll qpow(ll a, ll b) { ll ans = 1;    while (b) { if (b & 1)    ans *= a;        b >>= 1;        a *= a; }    return ans; }   
ll qpow(ll a, ll b, ll mod) { ll ans = 1; while (b) { if (b & 1)(ans *= a) %= mod; b >>= 1; (a *= a) %= mod; }return ans % mod; }

const int mod=1e9+7;
const int N=1e5+7;

int n,m,l,r;
int Log[N]; // 用来求log的
int stmax[N][22];
int stmin[N][22];

void fun(){//求log的函数
    Log[1]=0;
    for(int i=2;i<=n;i++)
        Log[i]=Log[i/2]+1;
}

bool search(int l,int r,ll k){//判断区间l到r是否可以
     int s=Log[r-l+1]; //求log的值
     int ma=max(stmax[l][s], stmax[r-(1<<s)+1][s]);//区间最大值
     int mi=min(stmin[l][s], stmin[r-(1<<s)+1][s]);//区间最小值
     if(ma-mi>k) return true; //判断是否大于k
     else return false;
}

int main(){
    while(cin>>n>>m){
        fun();
        for(int i=1;i<=n;i++) {cin>>stmax[i][0];stmin[i][0]=stmax[i][0];}
        for(int j=1;j<=21;j++)//构造st表
            for(int i=1;i+(1<<j)-1<=n;i++){
                stmax[i][j]=max(stmax[i][j-1],stmax[i+(1<<(j-1))][j-1]);
                stmin[i][j]=min(stmin[i][j-1],stmin[i+(1<<(j-1))][j-1]);
            }

        while(m--){
            ll k,ans=0;
            cin>>k;
            for(int i=1,j=1;i<=n;i++){
                while(!search(i,j,k)&&j<=n&&i<=j){//固定i的值,找到成立的j的最小值
                    j++;
                }
                if(j<=n) ans=ans+n-j+1; //如果某一子段可以,则无论后面加上什么数形成的数组都可以
            }
            cout<<ans<<endl;
        }
    }
    return 0;
}
全部评论

相关推荐

赏个offer求你了:友塔HR还专门加我告诉我初筛不通过😂
点赞 评论 收藏
分享
09-29 17:44
已编辑
蔚来_测(准入职员工)
//鲨鱼辣椒:见不了了我实习了四个月上周再投筛选了一天就给我挂了
点赞 评论 收藏
分享
11 1 评论
分享
牛客网
牛客企业服务