zoukankan      html  css  js  c++  java
  • “玲珑杯”ACM比赛 Round #19 B -- Buildings (RMQ + 二分)

    Start Time:2017-07-29 14:00:00 End Time:2017-07-29 16:30:00 Refresh Time:2017-07-29 16:42:55 Private

    B -- Buildings

    Time Limit:2s Memory Limit:128MByte

    Submissions:590Solved:151

    DESCRIPTION

    There are nn buildings lined up, and the height of the ii-th house is hihi.

    An inteval [l,r][l,r](lr)(l≤r) is harmonious if and only if max(hl,,hr)min(hl,,hr)kmax(hl,…,hr)−min(hl,…,hr)≤k.

    Now you need to calculate the number of harmonious intevals.

    INPUT
    The first line contains two integers n(1n2×105),k(0k109)n(1≤n≤2×105),k(0≤k≤109). The second line contains nn integers hi(1hi109)hi(1≤hi≤109).
    OUTPUT
    Print a line of one number which means the answer.
    SAMPLE INPUT
    3 1 1 2 3
    SAMPLE OUTPUT
    5
    HINT
    Harmonious intervals are: [1,1],[2,2],[3,3],[1,2],[2,3][1,1],[2,2],[3,3],[1,2],[2,3].
    【题意】给你一个序列,然后问你有多少个区间的最大值-最小值<=k。
    【分析】我们可以用RMQ来logn查询区间最大、最小值,然后枚举每一位最为区间右端点,向左二分左端点,将区间长度加到ans即可。
     
    #include <bits/stdc++.h>
    #define inf 0x3f3f3f3f
    #define met(a,b) memset(a,b,sizeof a)
    #define pb push_back
    #define mp make_pair
    #define inf 0x3f3f3f3f
    using namespace std;
    typedef long long ll;
    const int N = 2e5+50;
    const int mod = 1e9+7;
    const double pi= acos(-1.0);
    typedef pair<int,int>pii;
    int n,k;
    int a[N];
    int mn[N][20],mx[N][20],mm[N];
    void init() {
        for(int j=1; j<=mm[n]; ++j) {
            for(int i=1; i+(1<<j)-1<=n; ++i) {
                mn[i][j]=min(mn[i][j-1],mn[i+(1<<(j-1))][j-1]);
                mx[i][j]=max(mx[i][j-1],mx[i+(1<<(j-1))][j-1]);
            }
        }
    }
    int getmx(int l,int r) {
        int k = mm[r-l+1];
        return max(mx[l][k],mx[r-(1<<k)+1][k]);
    }
    int getmn(int l,int r) {
        int k = mm[r-l+1];
        return min(mn[l][k],mn[r-(1<<k)+1][k]);
    }
    int main(){
        mm[0]=-1;
        for(int i=1; i<N; ++i)mm[i]=(i&(i-1))?mm[i-1]:mm[i-1]+1;
        scanf("%d%d",&n,&k);
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
            mn[i][0]=mx[i][0]=a[i];
        }
        init();
        int l,r,res;
        ll ans=0;
        for(int i=1;i<=n;i++){
            l=1;r=i;res=i;
            while(l<=r){
                int mid=(l+r)/2;
                int maxn=getmx(mid,i);
                int minn=getmn(mid,i);
                if(maxn-minn>k)l=mid+1;
                else r=mid-1,res=mid;
            }
            ans+=i-res+1;
        }
        printf("%lld
    ",ans);
        return 0;
    }
  • 相关阅读:
    网络测量中基于Sketch方法的简单介绍
    Reading SBAR SDN flow-Based monitoring and Application Recognition
    Reading Meticulous Measurement of Control Packets in SDN
    Reading SketchVisor Robust Network Measurement for Sofeware Packet Processing
    ovs加dpdk在日志中查看更多运行细节的方法
    后缀数组
    (转载)LCA问题的Tarjan算法
    Codeforces Intel Code Challenge Final Round (Div. 1 + Div. 2, Combined) A. Checking the Calendar(水题)
    Vijos 1816统计数字(计数排序)
    卡特兰数
  • 原文地址:https://www.cnblogs.com/jianrenfang/p/7257227.html
Copyright © 2011-2022 走看看