f[i]=∑f[j] (sum[j]<=sum[i]).
sum为前缀和.
裸的DP是O(N^2)的,其实我们要找的j只需满足sum[j]<=sum[i],然后求和.
而树状数组天生就是干这个的.范围大,离散化一下就好了.
code:
/************************************************************** Problem: 2274 User: exponent Language: Pascal Result: Accepted Time:140 ms Memory:2568 kb ****************************************************************/ const maxn=100001; mo=1000000009; var s,t,p,q,f,c:array[0..maxn] of longint; n,i,num,pre,pos,rank:longint; procedure swap(var a,b:longint); var temp:longint; begin temp:=a; a:=b; b:=temp; end; procedure sort(l,r:longint); var i,j,mid:longint; begin i:=l; j:=r; mid:=s[(l+r)>>1]; while i<=j do begin while s[i]<mid do inc(i); while s[j]>mid do dec(j); if i<=j then begin swap(s[i],s[j]); swap(p[i],p[j]); inc(i); dec(j); end; end; if i<r then sort(i,r); if j>l then sort(l,j); end; function lowbit(i:longint):longint; begin lowbit:=i and (i xor (i-1)); end; procedure change(i,delta:longint); begin while i<=maxn do begin c[i]:=(c[i]+delta) mod mo; inc(i,lowbit(i)); end; end; function getsum(i:longint):longint; begin getsum:=0; while i>0 do begin getsum:=(getsum+c[i]) mod mo; dec(i,lowbit(i)); end; end; begin readln(n); for i:=1 to n do begin readln(num); s[i]:=s[i-1]+num; p[i]:=i; q[i]:=s[i]; end; sort(1,n); pre:=s[1]; t[p[1]]:=1; rank:=1; for i:=2 to n do if s[i]=pre then t[p[i]]:=rank else begin pre:=s[i]; inc(rank); t[p[i]]:=rank; end; f[0]:=1; change(1,1); for i:=1 to n do if q[i]>=0 then begin f[i]:=getsum(t[i]); change(t[i],f[i]); end; writeln(f[n]); end.