Luogu P2309 loidc,卖卖萌

题目链接:Click here

题目大意:给你一个长度为n的数串,问这个数串的sum为正数的子串个数

Solution:

我们先处理以下前缀和,记为\(s_i\)

则问题可以转化为求有多少对\(i,j\)满足\(j>i,s_j-s_{i-1}>0\)

我们把所有的\(s_i\)变成\(-s_i\),则问题就变成了满足\(i<j,s_{i-1}>s_j\)的点对个数

然后用树状数组求逆序对即可

Code:

#include<bits/stdc++.h>
#define lowbit(x) x&(-x)
using namespace std;
const int N=1e5+2;
long long ans;
int n,a[N],tree[N];
struct Pos{int id,val;}p[N];
inline bool cmp(Pos a,Pos b){return a.val==b.val?a.id<b.id:a.val<b.val;}
void add(int x){for(int i=x;i<=n+1;i+=lowbit(i))tree[i]++;}
int sum(int x){int re=0;for(int i=x;i>=1;i-=lowbit(i)) re+=tree[i];return re;}
int read(){
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    while(isdigit(ch)){x=x*10+ch-48;ch=getchar();}
    return x*f;
}
int main(){
    n=read();
    for(int i=1;i<=n;i++){
        a[i]=read();
        p[i].val=p[i-1].val-a[i];
        p[i].id=i+1;
    }p[0].id=1;sort(p,p+n+1,cmp);
    for(int i=0;i<=n;i++){
        ans+=sum(n+1)-sum(p[i].id);
        add(p[i].id);
    }printf("%lld\n",ans);
    return 0;
}

转载于:https://www.cnblogs.com/NLDQY/p/10961277.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值