TOJ 3425: Generic Cow Protests -- 树状数组

3425: Generic Cow Protests

Time Limit(Common/Java):1000MS/3000MS     Memory Limit:65536KByte
Total Submit: 46            Accepted:14

Description

Farmer John's N (1 <= N <= 100,000) cows are lined up in a row and numbered 1..N. The cows are conducting another one of their strange protests, 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 grouped and thus would like to arrange the cows into one or more contiguous groups 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, and 1, 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.

Input

* Line 1: A single integer: N

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

Output

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

Sample Input

4
2
3
-3
1

Sample Output

4

Source

USACO Feb 2011


http://www.verydemo.com/demo_c427_i28080.html 有详细的解答

#include 
     
     
      
      
#include 
      
      
       
       
#include 
       
       
        
        
#include 
        
        
         
         
#include 
         
         
           #include 
           #include 
           
             #include 
            
              #include 
             
               #include 
              
                #include 
               
                 #include 
                
                  #include 
                 
                   #include 
                  
                    #include 
                   
                     #include 
                    
                      #define mp make_pair using namespace std; typedef unsigned int ui; typedef long long ll; typedef unsigned long long ull; typedef pair 
                     
                       pii; typedef vector 
                      
                        vi; typedef vi::iterator vi_it; typedef map 
                       
                         mii; typedef priority_queue 
                        
                          pqi; typedef priority_queue 
                         
                           , greater 
                          
                            > rpqi; const int MAX_N = 100000 + 2; const int MOD = 1000000009; int sum[MAX_N]; int ordered_sum[MAX_N]; int c[MAX_N]; class Tree_Array { public: Tree_Array(int _n); void update(int pos, int v); int sum(int pos); private: int n; inline int lowbit(int x); }; Tree_Array::Tree_Array(int _n) : n(_n) { } inline int Tree_Array::lowbit(int x) { return x & (-x); } void Tree_Array::update(int pos, int v) { for (int i = pos; i <= n; i += lowbit(i)) { c[i] = (c[i] + v) % MOD; } } int Tree_Array::sum(int pos) { int ret = 0; for (int i = pos; i; i -= lowbit(i)) { ret = (ret + c[i]) % MOD; } return ret; } int main(int argc, char *argv[]) { // freopen("D:\\in.txt", "r", stdin); int n, a, i; cin >> n; Tree_Array ta(n); for (i = 1; i <= n; ++i) { scanf("%d", &a); ordered_sum[i] = sum[i] = sum[i - 1] + a; } sort(ordered_sum + 1, ordered_sum + n + 1); int *end = unique(ordered_sum + 1, ordered_sum + n + 1); for (i = 1; i < n; ++i) { int pos = lower_bound(ordered_sum + 1, end, sum[i]) - ordered_sum; int tmp = ta.sum(pos); if (sum[i] >= 0) { ++tmp; } ta.update(pos, tmp); } cout << (ta.sum(lower_bound(ordered_sum + 1, end, sum[n]) - ordered_sum) + (sum[n] >= 0)) % MOD << endl; return 0; } 
                           
                          
                         
                        
                       
                      
                     
                    
                   
                  
                 
                
               
              
             
            
         
        
        
       
       
      
      
     
     

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值