树状数组 hdu2227 Find the nondecreasing subsequences

题意:问不下降子序列有多少个

思路:用树状数组维护嘛。。假如树状数组节点i表示的是以A[i]结尾的不下降子序列有多少个,记为F[i]

那么我们,求A[i]的时候,相当于在[1,i-1]中找到<=A[i]的节点,加上对应的F值,最后再加一

这种动态规划的思想,只是用树状数组去优化了而已

然后因为A[i]范围非常大,,所以需要先排序一遍,然后二分用对应的下标去操作

#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<cstdio>
#include<string>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<functional>

using namespace std;
typedef long long LL;
typedef pair<int, int> PII;

const int MX = 1e5 + 5;
const int HS = 1000007;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;

int n;
LL S[MX], A[MX], B[MX];

LL sum(int x) {
    LL ret = 0;
    for(; x; x -= x & -x) {
        ret += S[x];
        ret %= mod;
    }
    return ret;
}

LL query(int L, int R) {
    return (sum(R) - sum(L - 1) + mod) % mod;
}

void update(int x, LL d) {
    for(; x <= n; x += x & -x) {
        S[x] += d;
        S[x] %= mod;
    }
}

int BS(LL A[], int L, int R, int x) {
    int l = L, r = R, m;
    while(l <= r) {
        m = (l + r) >> 1;
        if(A[m] == x) return m;
        if(A[m] < x)  l = m + 1;
        else        r = m - 1;
    }
    return -1;
}

int main() {
    //freopen("input.txt", "r", stdin);
    while(~scanf("%d", &n)) {
        memset(S, 0, sizeof(S));

        for(int i = 1; i <= n; i++) {
            scanf("%I64d", &A[i]);
            B[i] = A[i];
        }
        sort(A + 1, A + 1 + n);

        LL ans = 0, ret;
        for(int i = 1; i <= n; i++) {
            int pos = BS(A, 1, n, B[i]);
            ret = query(1, pos) + 1;
            update(pos, ret);
            ans = (ans + ret) % mod;
        }
        printf("%I64d\n", ans);
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值