題目連接:Click herec++
題目大意:給你一個長度爲n的數串,問這個數串的sum爲正數的子串個數git
咱們先處理如下前綴和,記爲\(s_i\)數組
則問題能夠轉化爲求有多少對\(i,j\)知足\(j>i,s_j-s_{i-1}>0\)spa
咱們把全部的\(s_i\)變成\(-s_i\),則問題就變成了知足\(i<j,s_{i-1}>s_j\)的點對個數code
而後用樹狀數組求逆序對便可get
#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; }