hdu 2227

Find the nondecreasing subsequences

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

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

题目描述 :求一段序列的上海上升序列的个数 dp[i]= sum(dp[j]+1) &&(a[j]<a[i])

因为a[j]<a[i] ,所以相当于求正序数的个数

求逆序数一般有三种解法 1 暴力 2 归并排序 3 树状数组

树状数组求法 :

原始序列为 5 4  1 2 3

int answer=0;

一 在1的位置上加一       answer+=sum(i-1); answer=0;

0 0 1 0 0

二在2的位置上加一       answer+=sum(3); answer=1;

0 0 1 1 0

三在3的位置上加一       answer+=sum(4); answer=3

0 0 1  1 1

四 在四的位置上加一  answer+=sum(1);answer=3;

0  1 1 1  1

五 在五的位置上加一  answer+=sum(0);answr=3;

1 1 1 1 1

此题要求所有的上升序列的个数,有了递推式应该很好求,

可是我陷入了一个误区 ,认为既然是递推式,那么就应该按照天然的顺序,逐个递推(因为计算当前状态值需要用到前面所有的状态值),

可是要求正序数的话需要从小到大,逐个放入,计算前面的数之和,瞬间就无语了,怎么办呢?观察递推式  dp[i]= sum(dp[j]+1) &&(a[j]<a[i])

如果从小到大放的话,假设放i位置,那么i之前的就是比它小的已经放过的,没有放的就是对i状态的值无影响的,先放还是后放对i

状态没有影响,这样我们就可以去掉对i来说的冗余信息,相当于只对 a[j] < a[i] 的 j 进行递推,

我们设 A[i]代表以i结尾的上升序列的个数,A[i]=sum(i-1)+1;sum(i-1)代表之前所有的上升序列的个数,sum(i-1) == A[1]+A[2]+A[3]+.....+A[i-1];

假设从小到大进行求解,利用暴力求和,时间复杂度太高,

那么我们利用树状数组进行点(A[i])修改和查询操作,时间复杂度降为 long(N);

也可利用线段树进行点修改和查询操作

采用树状数组,从小到大 ,放入 它自己的位置,然后更新A[i],那么答案就是sum(N);

假设原始序列为 5 4  1 2 3

0 0 0 0 0

0 0 1 0 0

0 0 1 2 0

0 0 1 2 4

0 1 1 2 4

1 1 1 2  4

那么答案就是1 + 1 + 1 + 2 + 4=9,利用树状数组进行求和

#include <iostream>
#include <cstdio>
#include <time.h>
#include <stdlib.h>
#include <cstring>
#include<algorithm>
#define M 100100
#define MOD 1000000007
#define LL  long long
using namespace std;
struct node
{
   LL value,id;
};
bool cmp (node a,node b)
   {
       if(a.value!=b.value)
       return a.value<b.value;
       else
       return a.id<b.id;
   }
node a[M];
LL dp[M];
LL c[M];
LL N;
void init()
{
   memset(a,0,sizeof(a));
   memset(dp,0,sizeof(dp));
   memset(c,0,sizeof(c));
}

//树状数组
LL lowbit(LL x)
{
   return x&(-x);
}

LL sum(LL x)
{
   LL ret=0;
   while(x>0)
   {
      ret=ret%MOD;
      ret+=c[x];
      x-=lowbit(x);
   }
    return ret%MOD;
}

void  add(LL x,LL extra)
{
    while(x <= N)
    {
      c[x]=c[x]%MOD;
      c[x]=c[x]+1+extra;     //A[i]加上i之前的所有的上升序列的个数 A[i]=sum(i-1)+1;sum(i-1)代表之前所有的上升序列的个数
      x+=lowbit(x);
    }
}

LL solve()
{
    add(a[1].id,0);
   //  answer+=sum(a[1].id);
    //printf("%lld\n",sum(a[1].id));
    for(int i=2;i<=N;i++)
    {
            add(a[i].id,sum(a[i].id-1));  //A[i]加上i之前的所有的上升序列的个数 A[i]=sum(i-1)+1;sum(i-1)代表之前所有的上升序列的个数
           // answer=answer % MOD;
           // answer+=sum(a[i].id);
        // printf("%lld\n",sum(a[i].id));
    }
    return sum(N) % MOD;
}

int main()
{
    while(~scanf("%d",&N))
    {
      init();
      for(int i=1;i<=N;i++)
      {
        scanf("%I64d",&a[i].value);
        a[i].id=i;
         //printf("%I64d  %I64d\n",a[i].value,a[i].id);
      }
      /*for(int i=1;i<=N;i++)
      {
       printf("%lld  %lld\n",a[i].value,a[i].id);

      }*/
          sort(a+1,a+N+1,cmp);

          printf("%I64d\n",solve());
    }

    return 0;
}
时间: 2024-10-26 06:01:47

hdu 2227的相关文章

HDU 2227 Find the nondecreasing subsequences (DP+树状数组+离散化)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2227 Find the nondecreasing subsequences                                  Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)                                             

HDU - 2227 Find the nondecreasing subsequences (树状数组 + 子序列 + 离散化)

HDU - 2227 Find the nondecreasing subsequences Time Limit: 5000MS   Memory Limit: 32768KB   64bit IO Format: %I64d & %I64u Submit Status Description How many nondecreasing subsequences can you find in the sequence S = {s1, s2, s3, ...., sn} ? For exa

HDU 2227 Find the nondecreasing subsequences dp思想 + 树状数组

http://acm.hdu.edu.cn/showproblem.php?pid=2227 用dp[i]表示以第i个数为结尾的nondecreasing串有多少个. 那么对于每个a[i] 要去找 <= a[i]的数字那些位置,加上他们的dp值即可. 可以用树状数组维护 #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algori

hdu 2227(dp+树状数组)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2227 Find the nondecreasing subsequences Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1466    Accepted Submission(s): 521 Problem Description

hdu 2227 树状数组+dp

题意是求一个数列的不递减的子序列的个数: 很显然,如果只用dp来做的话时间是O(n*n) 因为dp[i]为前i个数可能的方案,则状态转移方程为dp[i]=sum(dp[j],j<i&&num[j]<=num[i])+1 对小数据坑定能过 但大数据就超时了,这里用到了树状数组来优化: 先对num按数来进行排序,(这道题因为数据较大  用到了离散化) 因为更新是是按原序更新的,及i之前的num[j]一定比num[i]小,维护了不递减的原则,更新是从mark[i](表示原序列i在排序

hdu 2227 dp+树状数组优化

很容易可以想到状态转移方程: dp[i] = segma: dp[j] ( j < i && a[j] <= a[i] ), 其中dp[i]表示以a[i]结尾的不降子序列的个数. 但是n非常大,n^2的算法必然TLE,仔细想想其实式子右边是一个区间和的形式,即小于等于a[i]的a[j]的dp[j]的和,所以可以将a[i]离散化成t后将dp[i]的值存在t位置上,每次求解dp[i]就是查询一个前缀和,可以用树状数组来维护. 举个例子:对于1,50,13,34这四个数,离散化后变成

HDU 2227 Find the nondecreasing subsequences

树状数组+dp因为今天复习离散化于是手贱加了个离散化 题目大意 意思是给你一段序列,求里面的最长不下降子序列的长度. dp思想 这道题的dp方程非常的好推,看完题目的第一眼就已经推出了方程 设dp[i]表示以当前点为终点的序列方案.所以方程是 \[ dp[i] += (i>j\&\&a[i]\ge a[j])? dp[j]+1:1\ans=\sum_{i=1}^{n}dp[i] \] 但是一看这种方法就是\(n^2\)的复杂度,明显过不了,那怎么办呢? 优化 我们知道,我们最后求得一

BIT 树状数组 详解 及 例题

(一)树状数组的概念 如果给定一个数组,要你求里面所有数的和,一般都会想到累加.但是当那个数组很大的时候,累加就显得太耗时了,时间复杂度为O(n),并且采用累加的方法还有一个局限,那就是,当修改掉数组中的元素后,仍然要你求数组中某段元素的和,就显得麻烦了.所以我们就要用到树状数组,他的时间复杂度为O(lgn),相比之下就快得多.下面就讲一下什么是树状数组: 一般讲到树状数组都会少不了下面这个图: 下面来分析一下上面那个图看能得出什么规律: 据图可知:c1=a1,c2=a1+a2,c3=a3,c4

HDU 4287 Intelligent IME(字典树数组版)

Intelligent IME Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 4776    Accepted Submission(s): 2227 Problem Description We all use cell phone today. And we must be familiar with the intelligen