zoukankan      html  css  js  c++  java
  • Codeforces Round #510 (Div. 2) D. Petya and Array(离散化+反向树状数组)

    http://codeforces.com/contest/1042/problem/D

    题意

    给一个数组n个元素,求有多少个连续的子序列的和<t
    (1<=n<=200000,abs(a[i])<=1e9)

    思路

    • 将公式转化以下,sum[r]-sum[l-1]<t 变成 sum[r]<sum[l-1]+t
    • 可以考虑遍历每个r,先更新sum[r-1]+t,统计有多少满足条件的sum[l-1],反向树状数组维护即可

    实现细节

    • 对于每个r是更新他的sum[r-1]
    • 因为要统计>sum[r]的数有多少,但是反向树状数组是包含自己当前这个点的,所以要加一
    • 反向树状数组的右边界最好是数组大小
    #include<bits/stdc++.h>
    #define M 400005
    #define ll long long
    using namespace std;
    int tr[M];
    int n,tot,i;
    ll tp,p[M],x[M],ans,t;
    
    int lowbit(int x){return x&(-x);}
    
    void add(int x){
        while(x>0){
            tr[x]++;x-=lowbit(x);
        }
    }
    
    int qy(int x){
        x++;         //
        int ans=0;
        while(x<M){    //
           ans+=tr[x];x+=lowbit(x);
        }
       return ans;
    } 
    int fd(ll x){
        return lower_bound(p,p+tot,x)-p+1;
    }
    int main(){
        cin>>n>>t;
        tot=0;
        for(i=1;i<=n;i++){
            scanf("%lld",&x[i]);
            x[i]+=x[i-1];
            p[tot++]=x[i];
            p[tot++]=x[i]+t;
        }
        sort(p,p+tot);
        tot=unique(p,p+tot)-p;
        ans=0;
        for(i=1;i<=n;i++){
            add(fd(x[i-1]+t));   //
            ans+=qy(fd(x[i]));
            //cout<<ans<<endl;
        }
        cout<<ans;
    }
            
    
    
    
  • 相关阅读:
    Comparable VS Comparator
    Javascript中this关键字详解
    Runtime、System、Object
    JS IDE
    异常处理
    Throwable vs Exception
    8.4 Java 命名规范
    关键字、标识符、注释、变量
    Docker —— 从入门到实践
    RTC教程
  • 原文地址:https://www.cnblogs.com/VIrtu0s0/p/10003953.html
Copyright © 2011-2022 走看看