题解:
这道题一看就不难得出这是一道dp题,设sum[i]是a[1]-a[i]的和,那么显然可得当sum[i]-sum[j]>=0时dp[i]可以从dp[j]处转移,那么就把所有满足条件的dp[j]加起来。于是乎可得方程dp[i]=∑dp[j] (sum[i]>=sum[j])
给出一份可在某谷上过的代码:
#include<bits/stdc++.h>
#define M 1000000009
using namespace std;
long long A[100005];
int n;
long long dp[100005];
int read(){
int num=0,f=1;
char ch=getchar();
while(ch>'9'||ch<'0'){
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
num=(num<<1)+(num<<3)+ch-'0';
ch=getchar();
}
return num*f;
}
int main(){
n=read();
int x=0;
for(int i=1;i<=n;i++){
A[i]=read();
A[i]+=A[i-1];
if(!x){
if(A[i]>0){
x=i;
dp[x]=1;
}
continue;
}
}
if(!x||A[n]<0){
puts("0");
return 0;
}
for(int i=x+1;i<=n;i++){
if(A[i]>=0){
dp[i]=1;
for(int j=x;j<i;j++){
if(dp[j]&&(A[i]-A[j]>=0)){
dp[i]+=dp[j];
dp[i]%=M;
}
}
}
}
cout<<dp[n]%M;
}
然而众所周知某谷上的数据实在太水了,只要复杂一点的数据这个代码就只有90了
所以要用树状数组或线段树维护;
#include<bits/stdc++.h>
#define mod 1000000009
#define ll long long
using namespace std;
int n,size;
int a[1001000];
int sum[1001000];
int c[1001000];
struct node {
int bh,v,lsh;
} Tree[1001000];
int read() {
int num=0,f=1;
char ch=getchar();
while(ch>'9'||ch<'0') {
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9') {
num=(num<<1)+(num<<3)+ch-'0';
ch=getchar();
}
return num*f;
}
int lowbit(int x) {
return x&(-x);
}
void add(int x,int v) {
while(x<=size) {
c[x]=(c[x]+v)%mod;
x+=lowbit(x);
}
}
int ask(int x) {
int ans=0;
while(x>0) {
ans=(ans+c[x])%mod;
x-=lowbit(x);
}
return ans;
}
bool com1(node x,node y) {
return x.v<y.v;
}
bool com2(node x,node y) {
return x.bh<y.bh;
}
int main() {
n=read();
for(int i=1; i<=n; i++) {
Tree[i].v=read()+Tree[i-1].v;
Tree[i].bh=i;
}
sort(Tree,Tree+n+1,com1);
int cnt=1;
Tree[0].lsh=1;
for(int i=1; i<=n; i++) {
if(Tree[i].v==Tree[i-1].v)
Tree[i].lsh=cnt;
else Tree[i].lsh=++cnt;
}
size=cnt;
sort(Tree,Tree+n+1,com2);
add(Tree[0].lsh,1);
int ans;
for(int i=1; i<=n; i++) {
ans=ask(Tree[i].lsh);
add(Tree[i].lsh,ans);
}
printf("%d",ans);
}