• [CodeForces]1042D


    大意:求一个序列有几个子序列的和小于给定值,里面的数有正有负,序列长度≤200000。

    列个式子,其实求的是sum[r]-sum[l-1]<T

    sum[r]-T<sum[l-1]

    所以我们可以枚举r,然后用树状数组找小于sum[r]-T的数的个数。记得要在树状数组里先加一个0,表示L取1,即从头开始。

    #include <iostream>
    #include <algorithm>
    #include <cmath>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    const int N=100005;
    long long n,pre[N],a[N],ans,t[N],T,sum,tp[N];
    void add(long long i) {for(;i<N;i+=i&-i) t[i]++;}
    long long ask(long long i) {long long res=0;for(;i;i-=i&-i) res+=t[i];return res;}
    int main() {
        scanf("%lld%lld",&n,&T);
        for(int i=1;i<=n;i++) scanf("%lld",&a[i]),pre[i]=pre[i-1]+a[i],tp[i]=pre[i];
        sort(tp+1,tp+2+n);
        int u=unique(tp+1,tp+2+n)-tp-1;
        for(int i=0;i<=n;i++) pre[i]=lower_bound(tp+1,tp+1+u,pre[i])-tp;
        add(pre[0]);
        for(int i=1;i<=n;i++) {
            int pos=lower_bound(tp+1,tp+1+u,tp[pre[i]]-T)-tp;
            if(tp[pos]!=tp[pre[i]]-T) pos--;    
            ans+=i-ask(pos);
            add(pre[i]);
        }
        cout<<ans<<endl;
        return 0;
    }
    Petya and Array
    我是咸鱼。转载博客请征得博主同意Orz
  • 相关阅读:
    【Daily Scrum】11-18:Postmortem of sprint 1
    【Daily Scrum】11-17
    【Daily Scrum】11-14
    【Daily Scrum】11-13
    【Daily Scrum】11-12
    【Daily Scrum】12-04
    【Daily Scrum】12-03
    【Review】Postmortem of Sprint 2 and next planning
    【Daily Scrum】11-28
    【Daily Scrum】11-27
  • 原文地址:https://www.cnblogs.com/sdfzhsz/p/9669615.html
Copyright © 2020-2023  润新知