【题解】
很容易可以写出朴素DP方程f[i]=sigma f[j] (sum[i]>=sum[j],1<=j<=i). 于是我们用权值树状数组优化即可。
1 #include<cstdio> 2 #include<algorithm> 3 #define N 200010 4 #define rg register 5 #define LL long long 6 #define Mod (1e9+9) 7 using namespace std; 8 int n,n2; 9 LL t[N],f[N],sum[N],a[N]; 10 inline int read(){ 11 int k=0,f=1; char c=getchar(); 12 while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar(); 13 while('0'<=c&&c<='9')k=k*10+c-'0',c=getchar(); 14 return k*f; 15 } 16 inline void MOD(LL &k){if(k>=Mod) k-=Mod;} 17 inline void add(int x,int y){for(;x<=n2;x+=x&-x) t[x]+=y,MOD(t[x]);} 18 inline LL query(int x){ 19 LL ret=0; for(;x;x-=x&-x) ret+=t[x],MOD(ret); return ret; 20 } 21 int main(){ 22 n=read(); 23 for(rg int i=1;i<=n;i++) a[i]=sum[i]=read()+sum[i-1]; 24 for(rg int i=1;i<=n;i++) if(sum[i]>=0) f[i]++; 25 sort(a+1,a+1+n); n2=unique(a+1,a+1+n)-a-1; 26 for(rg int i=1;i<=n;i++) sum[i]=lower_bound(a+1,a+1+n2,sum[i])-a; 27 // for(rg int i=1;i<=n;i++) printf("%lld ",sum[i]); puts(""); 28 for(rg int i=1;i<=n;i++){ 29 f[i]+=query(sum[i]); 30 add(sum[i],f[i]); 31 } 32 printf("%lld ",f[n]); 33 return 0; 34 }