• 2019牛客暑期多校训练营(第三场)G.Removing Stones(ST+分治)


    题意:给你n堆石子 每堆有ai个 现在问你有多少个连续的区间保证最大值小于等于该区间和的两倍

    思路:我们可以考虑每个区间的分割点 总是该区间的最大值 所以我们只要ST找到该区间的最大值 然后每次都枚举较小的半区间 二分找到刚号满足的区间 这样我们就可累加个数了

    注意边界的情况 本人用lower_bound找bug找到自闭

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 3e5+7;
    const int inf = 0x3f3f3f3f;
    typedef long long ll;
    const ll mod = 1e7+9;
    int a[N],f[N][30],mm[N];
    ll sum[N];
    int n;
    int max(int i,int j){
        if(a[i]>=a[j]) return i;
        else return j;
    }
    void preST(int len){
        mm[0]=-1;
        for(int i=1;i<=len;i++){
            mm[i]=((i&(i-1))==0)?mm[i-1]+1:mm[i-1];
            f[i][0]=i;
        }
        for(int j=1;j<=mm[len];j++)
            for(int i=1;i<=(len-(1<<j)+1);i++)
                f[i][j]=max(f[i][j-1],f[i+(1<<(j-1))][j-1]);
    //[i,i+2^j-1]最大值即是 i~i+2^(j-1)和 i+2^(j-1)~i+2^(j-1)+2^(j-1) 这两半区间的较大值
    }
    int queryST(int l,int r){
        int k=mm[r-l+1]; //保证k满足 2^k<r+l-1<=2^(k+1)
        return max(f[l][k],f[r-(1<<k)+1][k]);
    }
    ll ans=0;
    void solve(int l,int r){
        if(l>=r) return ;
        int mid=(l+r)>>1;
        int x=queryST(l,r);
        if(x<=mid){
            for(int i=l;i<=x;i++){
                int po=lower_bound(sum+x,sum+r+1,sum[i-1]+2*a[x])-sum;
                ans+=(r-po+1);
            }
        }else{
            for(int i=x;i<=r;i++){
                int po=upper_bound(sum+l-1,sum+x,sum[i]-2*a[x])-sum;
                ans+=(po-l+1);
            }
        }
        solve(l,x-1);
        solve(x+1,r);
    }
    int main(){
    //    ios::sync_with_stdio(false);
    //    cin.tie(0); cout.tie(0);
        int t; scanf("%d",&t);
        while(t--){
            scanf("%d",&n);
            ans=0;
            for(int i=1;i<=n;i++)
                scanf("%d",a+i),sum[i]=sum[i-1]+a[i];
            preST(n);
            solve(1,n);
            printf("%lld
    ",ans);
        }
    }
  • 相关阅读:
    ios开发-2015-07-19
    ios开发-2015-07-18
    ios开发-2015-07-17
    ios开发-2015-07-16
    ios开发-2015-07-15
    ios开发-2015-07-14
    ios开发-2015-07-13
    Selenium源码分析之WebDriver
    webdriver实现原理 分类: Selenium 2015-07-16 00:16 11人阅读 评论(0) 收藏
    webdriver实现原理
  • 原文地址:https://www.cnblogs.com/wmj6/p/11290864.html
Copyright © 2020-2023  润新知