洛谷P2344 奶牛抗议

题目背景

Generic Cow Protests, 2011 Feb

题目描述

约翰家的N 头奶牛正在排队游行抗议。一些奶牛情绪激动,约翰测算下来,排在第i 位的奶牛的理智度为Ai,数字可正可负。

约翰希望奶牛在抗议时保持理性,为此,他打算将这条队伍分割成几个小组,每个抗议小组的理智度之和必须大于或等于零。奶牛的队伍已经固定了前后顺序,所以不能交换它们的位置,所以分在一个小组里的奶牛必须是连续位置的。除此之外,分组多少组,每组分多少奶牛,都没有限制。

约翰想知道有多少种分组的方案,由于答案可能很大,只要输出答案除以1000000009 的余数即可。

输入输出格式

输入格式:

 

• 第一行:单个整数N,1 ≤ N ≤ 100000

• 第二行到第N + 1 行:第i + 1 行有一个整数Ai,−10^5 ≤ Ai ≤ 10^5

 

输出格式:

 

单个整数:表示分组方案数模1000000009 的余数

 

输入输出样例

输入样例#1:
4
2
3
-3
1
输出样例#1:
4

说明

解释:如果分两组,可以把前三头分在一组,或把后三头分在一组;如果分三组,可以把中间两头分在一组,第一和最后一头奶牛自成一组;最后一种分法是把四头奶牛分在同一组里。

分析:求方案数的解决方法可以用数学方法和dp,这道题我找不出数学数学方法来,只能dp.本来我的状态考虑为f[i][j]表示前j头牛分i组,可是这个i并不确定,而且O(n^3)的dp,直接超时了,那么我们去掉这一维,f[i]表示前i头牛的分组,f[i]=∑f[j](a[j] + a[j + 1] +...+a[i] >= 0),转换成前缀和就是s[j] <= s[i],那么怎么找j < i并且s[j] <= s[i]的数呢?当然是树状数组啦!但是由于s可能过大,需要先离散化一下.

dp中如果状态中的一维不能确定,可以省去这一维,通常可以用树状数组优化满足两个条件i<j&&s[i]<s[j]的题,数据太大需要离散化.

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>

using namespace std;

const int mod = 1000000009;

int n,cnt = 1,ans,c[100010];

struct node
{
     int a,id,newid;    
}e[100010];

bool cmp(node a,node b)
{
    return a.a < b.a;
}

bool cmp2(node a,node b)
{
    return a.id < b.id;
}

void add(int x,int d)
{
    while (x <= cnt)
    {
        c[x] = (c[x] + d) % mod;
        x += x & (-x);
    }
}

int query(int x)
{
    int res = 0;
    while (x)
    {
        res = (res + c[x]) % mod;
        x -= x & (-x);
    }
    return res;
}

int main()
{
    scanf("%d",&n);
    e[0].a = 0;
    e[0].id = 0;
    for (int i = 1;i <= n; i++)
    {
    int t;
    scanf("%d",&t);
    e[i].a = e[i-1].a + t; 
    e[i].id = i;
    }
    sort(e,e + 1 + n,cmp);
    e[0].newid = 1;
    for (int i = 1; i <= n; i++)
    {
        if (e[i].a != e[i-1].a)
        e[i].newid = ++cnt;
        else
        e[i].newid = cnt;
    }
    sort(e,e + 1 + n,cmp2);
    add(e[0].newid,1);
    for (int i = 1; i <= n; i++)
    {
        ans = query(e[i].newid);
        add(e[i].newid,ans);
    }
    printf("%d\n",ans);

    return 0;
}

 

posted @ 2017-09-11 22:04 zbtrs 阅读(...) 评论(...) 编辑 收藏