PIPI得到了一个数组作为他的新年礼物,他非常喜欢这个数组!
在仔细研究了几天之后,PIPI成功的将这个数组拆成了若干段,并且每段的和都不为0!
现在PIPI希望知道,这样的拆分方法一共有多少种?
两种拆分方法被视作不同,当且仅当数组断开的所有位置组成的集合不同。
多组数据。
每组输入的第一行为一个正整数N,表示这个数组的长度
第二行为N个整数A1~AN,描述PIPI收到的这个数组
对于40%的数据,满足1<=N<=10
对于100%的数据,满足1<=N<=100000, |Ai|<=100
输出
对于每组输入,输出一行Ans,表示拆分方案的数量除以(10^9+7)的余数。
5
1 -1 0 2 -2
5
#include
using namespace std;
typedef long long ll;
const int N = 1e5+10;
const int mod= 1e9+7;
ll n,ans,dp[N],sum;
map<ll,ll> Hash;
int main(){
int i,x;
while(scanf("%d",&n)!=EOF){
Hash.clear();sum=0;Hash[0]=1;ans=1;
for(i=0;i<n;i++){
scanf("%d",&x);
sum+=x;
dp[i]=(ans-Hash[sum]+mod)%mod;
Hash[sum]=(Hash[sum]+dp[i])%mod;
ans=(ans+dp[i])%mod;
}
printf("%d\n",dp[n-1]);
}
return 0;
}
分析
f[i] 等于 f[0] … f[i-1] 中若干项的和。具体是哪些项呢? 是那些满足s[j] != s[i]的f[j]。
比如
num 3 -1 -1 1
sum 3 2 1 2
dp 1 2 4
dp[3]=8-Hash[2]=8-2=6
在sum[i]==sum[j]表示
表示num[i+1]+num[i+2]+…+num[j]==0
由此可知在划分中i+1到j不可划分到一起(和为0)
Hash[sum[i]]记录了0到i的划分方案数,即不可行的
ans-Hash[sum[i]]即为可行方案数