HDOJ 题目2227 Find the nondecreasing subsequences(树状数组,离散化,DP)

本文探讨了如何在一个整数序列中找出所有非递减子序列的方法,并提供了一段使用C++实现的具体代码示例。文章包括问题描述、输入输出样例及AC代码,适合对算法竞赛感兴趣的学习者。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Find the nondecreasing subsequences

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1728    Accepted Submission(s): 631


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
  
3 1 2 3
 

Sample Output
  
7
 

Author
8600
 

Recommend
lcy   |   We have carefully selected several similar problems for you:   3450  2642  3030  3015  3016 
ac代码
153526982015-11-02 18:35:20Accepted22271123MS7632K1190 BG++XY_

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<map>
#define INF 0x3f3f3f3f
#define LL long long
#define mod 1000000007
using namespace std;
int val[100010],t[100010];
int a[100010],cnt;
int lowbit(int x)
{
    return x&(-x);
}
void add(int p,int val)
{
    while(p<=cnt)
    {
        a[p]=(a[p]+val)%mod;
        p+=lowbit(p);
    }
}
int getsum(int x)
{
    int ans=0;
    while(x>0)
    {
        ans=(ans+a[x])%mod;
        x-=lowbit(x);
    }
    return ans;
}
int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        int i;
        memset(a,0,sizeof(a));
        for(i=1;i<=n;i++)
        {
            scanf("%d",&val[i]);
            t[i]=val[i];
        }
        sort(t+1,t+n+1);
        cnt=unique(t+1,t+1+n)-(t+1);
        map<int ,int>mp;
        for(i=1;i<=cnt;i++)
        {
            mp[t[i]]=i;
        }
        int ans=0;
        add(1,1);
        for(i=1;i<=n;i++)
        {
            int x=getsum(mp[val[i]]);
           // printf("%d\n",x);
            ans=(ans+x)%mod   ;
            add(mp[val[i]],x);
        }
        printf("%d\n",ans);
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值