Find the nondecreasing subsequences--(树状数组)

来源:互联网 发布:淘宝信誉多少一个皇冠 编辑:程序博客网 时间:2024/05/23 20:15

Problem Description
How many nondecreasing subsequences can you find in the sequence S = {s1, s2, s3, ...., sn} ? For example, we assume that S = {1, 2, 3}, and you can find seven nondecreasing subsequences, {1}, {2}, {3}, {1, 2}, {1, 3}, {2, 3}, {1, 2, 3}.
 

Input
The input consists of multiple test cases. Each case begins with a line containing a positive integer n that is the length of the sequence S, the next line contains n integers {s1, s2, s3, ...., sn}, 1 <= n <= 100000, 0 <= si <= 2^31.
 

Output
For each test case, output one line containing the number of nondecreasing subsequences you can find from the sequence S, the answer should % 1000000007.
 

Sample Input
31 2 3
 

Sample Output
7

题意:求一个有序集合中能构成的非递减序列有多少个

题目是简单的树状数组,难点在怎么求这个个数,设a[i]是由i组成的非递减序列个数,tree是a数组产生的树状数组,然后加入i后新产生的序列个数a[i]=前面所有不比他大的数产生序列个数之和(sum(i))+1(这个数本身);

结果就是sum(n);

由于数据过大,需要离散化,而且根据AC代码可以发现可能存在重复的si,也就是结果中可以有重复的集合{si}

代码:

#include<iostream>#include<string>#include<cstdio>#include<algorithm>#include<cmath>#include<iomanip>#include<queue>#include<cstring>#include<map>#include<vector>using namespace std;typedef long long ll;#define M 100005#define mod 1000000007struct node{    ll val;    int id;    bool operator <(const node & obj)const    {        return val<obj.val||(val==obj.val&&id<obj.id);    }}a[M];int n;int b[M];ll tree[M];inline int lowbit(int i){    return i&(-i);}void add(int i,ll v){    while(i<=n)    {        tree[i]+=v;        i+=lowbit(i);    }}ll sum(int i){    ll res=0;    while(i>0)    {        res=(res+tree[i])%mod;        i-=lowbit(i);    }    return res;}int main(){    int i;    while(scanf("%d",&n)!=EOF)    {        for(i=1;i<=n;i++)        {            scanf("%I64d",&a[i].val);            a[i].id=i;        }        sort(a+1,a+n+1);        memset(tree,0,sizeof(tree));        b[a[1].id]=1;        for(i=2;i<=n;i++)            b[a[i].id]=i;        for(i=1;i<=n;i++)        {            add(b[i],sum(b[i])+1);        }        printf("%I64d\n",sum(n));    }    return 0;}


阅读全文
0 0