hdu 2227Find the nondecreasing subsequences(树状数组+dp+离散化)

题目链接:点击打开链接

题意描述:给定一个序列,找出其中递增子序列的数量?

解题思路:

1、dp[i]:表示以元素i结尾的子序列的数量,则d[j]=sum(d[i])+1;其中(j>=i且j的下标大于i)

2、此刻我们可以联想到树状数组,按数组下标从小到大的顺序插入元素,那么d[j]就等于sum(j)+1;

3、由于数据范围比较大,我们采用离散化处理即可

代码:

#include <cstdio>
#include <algorithm>
#include <cstring>
#define MOD 1000000007
using namespace std;
struct node{
    long long v;
    int pos;
    int rv;
}d[100010];
int n,rv;
bool cmp1(node a,node b){
    if(a.v==b.v)
        return a.pos<b.pos;
    return a.v<b.v;
}
bool cmp2(node a,node b){
    return a.pos<b.pos;
}
int C[100010];
int lowbit(int x){
    return x&(-x);
}
int sum(int x){
    long long ret=0;
    while(x>0){
        ret+=C[x];
        ret%=MOD;
        x-=lowbit(x);
    }
    return (int)ret;
}
void add(int x,int v){
    while(x<=rv){
        C[x]=(C[x]+(long long)v)%MOD;
        x+=lowbit(x);
    }
}
int main(){
    while(scanf("%d",&n)==1){
        for(int i=0;i<n;++i){
            scanf("%I64d",&d[i].v);
            d[i].pos=i;
        }
        sort(d,d+n,cmp1);
        rv=0;
        for(int i=0;i<n;++i)
            d[i].rv=++rv;
        sort(d,d+n,cmp2);
        memset(C,0,sizeof(C));
        long long ans=0;
        for(int i=0;i<n;++i){
            add(d[i].rv,sum(d[i].rv-1)+1);
            ans+=sum(d[i].rv-1)+1;
            ans%=MOD;
        }
        printf("%d\n",(int)ans);
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-03 14:42:46

hdu 2227Find the nondecreasing subsequences(树状数组+dp+离散化)的相关文章

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 5877 Weak Pair(树状数组+dfs+离散化)

http://acm.hdu.edu.cn/showproblem.php?pid=5877 题意: 给出一棵树,每个顶点都有权值,现在要你找出满足要求的点对(u,v)数,u是v的祖先并且a[u]*a[v]<=k. 思路: 转化一下,a[v]<=k/a[u],k/a[u]的最大值也就是k/a[v],也就是寻找<=k/a[v]的个数,到这儿,是不是很像树状数组? 我们只需要从根开始dfs,插入到树状数组中,并且查询即可.注意这道题目需要离散化一下. 1 #include <iostr

Codeforces 597C. Subsequences (树状数组+dp)

题目链接:http://codeforces.com/contest/597/problem/C 给你n和数(1~n各不同),问你长为k+1的上升自序列有多少. dp[i][j] 表示末尾数字为i 长度为j的上升子序列个数,但是dp数组是在树状数组的update函数中进行更新. update(i, val, j)函数表示在i的位置加上val,更新dp[i][j]. sum(i, j)就是求出末尾数字小于等于i 且长度为j的子序列有多少个. 1 //#pragma comment(linker,

【树状数组+dp+离散化】Counting Sequences

https://www.bnuoj.com/v3/contest_show.php?cid=9149#problem/G [题意] 给定一个数组a,问这个数组有多少个子序列,满足子序列中任意两个相邻数的差(绝对值)都不大于d. [思路] 首先,朴素的dp思想: dp[i]为以a[i]结尾的子问题的答案,则dp[i]=sum(dp[k]),k<i&&|a[k]-a[i]|<=d 但是时间复杂度为O(n^2),会超时. 我们可以这样想: 如果数组a排好序后,dp[i]就是区间(a[

hdu 3030 Increasing Speed Limits (离散化+树状数组+DP思想)

Increasing Speed Limits Time Limit: 2000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 481    Accepted Submission(s): 245 Problem Description You were driving along a highway when you got caught by the road p

HDU 2852 KiKi&#39;s K-Number (树状数组 &amp;&amp; 二分)

题意:给出对容器的总操作次数n, 接下来是这n个操作.这里对于一个容器提供三种操作, 分别是插入.删除和查找.输入0  e表示插入e.输入1  e表示删除e,若元素不存在输出No Elment!.输入2  e  k表示查找比e大且第k大的数, 若不存在则输出Not Find! 分析:这里考虑树状数组做的原因是在第三个操作的时候, 只要我们记录了元素的总数, 那通过求和操作, 便能够高效地知道到底有多少个数比现在求和的这个数要大, 例如 tot - sum(3)就能知道整个集合里面比3大的数到底有

HDU 3584 Cube (三维 树状数组)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3584 Cube Problem Description Given an N*N*N cube A, whose elements are either 0 or 1. A[i, j, k] means the number in the i-th row , j-th column and k-th layer. Initially we have A[i, j, k] = 0 (1 <= i, 

HDU 5592 ZYB&#39;s Premutation(树状数组+二分)

题意:给一个排列的每个前缀区间的逆序对数,让还原 原序列. 思路:考虑逆序对的意思,对于k = f[i] - f[i -1],就表示在第i个位置前面有k个比当前位置大的数,那么也就是:除了i后面的数字之外,它是在剩下的数字当中第k+1大的. 知道这个之后,可以用树状数组来帮助找出剩下的数中第k大的数,刚开始我们可以让1-n中每个元素都标记为1,那么他们的前缀和就代表它是第几小.所以,我们可以对于他们的和来二分快速寻找第k大数.其实在树状数组里面是按照第(i-k)小来找的.找完之后要删除这个元素的

hdu 5592 ZYB&#39;s Game 树状数组

ZYB's Game Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5592 Description ZYB has a premutation P,but he only remeber the reverse log of each prefix of the premutation,now he ask you to restore the premutation