题目描述

Farmer John's N (1 <= N <= 100,000) cows are lined up in a row andnumbered 1..N. The cows are conducting another one of their strangeprotests, so each cow i is holding up a sign with an integer A_i(-10,000 <= A_i <= 10,000).

FJ knows the mob of cows will behave if they are properly groupedand thus would like to arrange the cows into one or more contiguousgroups so that every cow is in exactly one group and that every group has a nonnegative sum.

Help him count the number of ways he can do this, modulo 1,000,000,009.

By way of example, if N = 4 and the cows' signs are 2, 3, -3, and1, then the following are the only four valid ways of arranging the cows:

(2 3 -3 1)

(2 3 -3) (1)

(2) (3 -3 1)

(2) (3 -3) (1)

Note that this example demonstrates the rule for counting different orders of the arrangements.

给出n个数,问有几种划分方案(不能改变数的位置),使得每组中数的和大于等于0。输出方案数除以 1000000009的余数。

输入

* Line 1: A single integer: N
* Lines 2..N + 1: Line i + 1 contains a single integer: A_i

输出

* Line 1: A single integer, the number of arrangements modulo 1,000,000,009.

样例输入

4
2
3
-3
1

样例输出

4


题解

dp+树状数组

设dp[i]为前i个数的划分方案数。

则易推出dp[i]=∑dp[j](sum[j]≤sum[i],j<i)。

那么可以用树状数组维护sum[j]在区间内的dp[j]的和。

由于sum过大且可能出现非正数,所以要先将sum离散化。

#include <cstdio>
#include <algorithm>
#define MOD 1000000009
using namespace std;
struct data
{
int sum , p;
}a[100010];
int f[100010] , dp[100010] , v[100010] , top;
bool cmp1(data a , data b)
{
return a.sum < b.sum;
}
bool cmp2(data a , data b)
{
return a.p < b.p;
}
void add(int p , int x)
{
int i;
for(i = p ; i <= top ; i += i & (-i))
f[i] = (f[i] + x) % MOD;
}
int query(int p)
{
int i , ans = 0;
for(i = p ; i ; i -= i & (-i))
ans = (ans + f[i]) % MOD;
return ans;
}
int main()
{
int n , i , t;
scanf("%d" , &n);
for(i = 1 ; i <= n ; i ++ )
scanf("%d" , &t) , a[i].sum = a[i - 1].sum + t , a[i].p = i;
sort(a , a + n + 1 , cmp1);
v[0] = 0x80000000;
for(i = 0 ; i <= n ; i ++ )
{
if(a[i].sum != v[top]) v[++top] = a[i].sum;
a[i].sum = top;
}
sort(a , a + n + 1 , cmp2);
dp[0] = 1;
add(a[0].sum , 1);
for(i = 1 ; i <= n ; i ++ )
dp[i] = query(a[i].sum) , add(a[i].sum , dp[i]);
printf("%d\n" , dp[n]);
return 0;
}

最新文章

  1. 基于MVC4+EasyUI的Web开发框架形成之旅--权限控制
  2. 根据PHP手册什么叫作变量的变量?
  3. 应用越来越广泛的css伪类
  4. 解决VS2012新建MVC4等项目时,收到加载程序集“NuGet.VisualStudio.Interop…”的错误
  5. double array trie 插入结点总结
  6. innodb master主线程
  7. 我的第一个QML Button的实现
  8. 微信小程序首页总结
  9. 网站被k到可以使用关键词搜索到首页优化总结
  10. scala mkstring
  11. my live boadband
  12. Keras 资源
  13. echo -n 和echo -e 参数意义
  14. SpringBoot在Kotlin中的实现(二)
  15. (转)tcp和udp能否发送0字节的数据包
  16. RPC和RabbitMQ
  17. 前端 css+js实现返回顶部功能
  18. Java之File与递归
  19. PHP面试系列 之框架(二)---- 常见框架的特性
  20. sencha touch extend 单继承 和 mixins 实现多继承

热门文章

  1. 北京Uber优步司机奖励政策(2月17日)
  2. 北京Uber优步司机奖励政策(12月14日)
  3. NB-IOT连接移动onenet平台流程
  4. redis 学习笔记二
  5. c的多态
  6. join_tab计算代价
  7. hackhttp模板的介绍
  8. Qt-QML-安卓编译问题
  9. Python基础 之 数据类型
  10. SIFT特征原理与理解