您的位置:首页 > 产品设计 > UI/UE

线段树 HDU 2227 Find the nondecreasing subsequences

2012-09-26 12:40 399 查看
题目链接: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 __int64

const 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: