线段树 HDU 2227 Find the nondecreasing subsequences

来源:互联网 发布:网络广告语 红酒 编辑:程序博客网 时间:2024/05/17 05:13

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2227

代码风格:notonlysuccess


题目意思:求有多少个不下降子序列

算法:线段树 离散化

思路:每一次插入前记录已经插入的数中比它小的有k个子序列满足条件,以插入值的大小建树,在该点保存的数值为k+1;

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;#define lson l, m, rt << 1#define rson m+1, r, rt << 1 | 1#define mid int m = (l+r) >> 1#define LL __int64const int mod = 1000000007;LL w[1231564], a[123546], p[456456];void PushUp(int rt){    p[rt] = p[rt << 1] + p[rt << 1 | 1];    p[rt] %= mod;}void update(int d, LL k, int l, int r, int rt){    if(l == r)    {        p[rt] += k;        return ;    }    mid ;    if(d <= m)        update(d, k, lson);    else update(d, k, rson);    PushUp(rt);}int bin(LL key, int r){    int l = 0;    while(l <= r)    {        mid ;        if(w[m] == key)            return m;        if(key < w[m])            r = m - 1;        else l = m+1;    }    return -1;}LL query(int L, int R, int l, int r, int rt ){    if(L <= l && r <= R)    {        return p[rt];    }    mid ;    LL ret = 0;    if(L <= m)        ret += query(L, R, lson);    if(m < R)        ret += query(L, R, rson);    return ret % mod;}int main(){    int n;    while(scanf("%d", &n) != EOF)    {        int i;        for(i = 0; i < n; i ++)        {            scanf("%I64d", &a[i]);            w[i] = a[i];        }        sort(w, w+n);        int m = 1;        for(i = 1; i < n; i ++)        {            if(w[i] != w[i-1])                w[m ++ ] = w[i];        }        LL ret = 0;        memset(p, 0, sizeof(p));        for(i = 0; i < n; i ++)        {            int ww = bin(a[i], m-1);            int k = 1;        //    if(ww != 0)            k = query(0, ww, 0, m-1, 1);            update(ww, k+1, 0, m-1, 1);            ret += k+1;        }        printf("%I64d\n", ret % mod);    }    return 0;}


原创粉丝点击