• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
james1207

博客园    首页    新随笔    联系   管理    订阅  订阅

HDU 2227 Find the nondecreasing subsequences (线段树)


 

Find the nondecreasing subsequences

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

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
 

 

 

解题思路: 每进来一个数,方法数是原来所有小于等于它的数的方法数之和+1,然后再把这个数添加进为原来的数,下面依次循环。

100000个数,但是数值比较大,所以离散化一下,线段树来维护,每次lg的操作

因此总效率 O(n^lgn)

 



 

#include <iostream>
#include <cstdio>
#include <map>
#include <algorithm>
using namespace std;

const int maxn=100010;
const int yu= 1000000007;
int n;
unsigned int data[maxn];

map <unsigned int,int> mp;

struct node{
	int l,r;
	unsigned c;	
}a[maxn*4];

void build(int l,int r,int k){
	a[k].l=l;a[k].r=r;a[k].c=0;
	if(l<r){
		int mid=(l+r)/2;
		build(l,mid,2*k);
		build(mid+1,r,2*k+1);
	}
}

void insert(int l,int r,int c,int k){
	a[k].c=(a[k].c+c)%yu;
	if(l<=a[k].l && a[k].r<=r) return;
	else{
		int mid=(a[k].l+a[k].r)/2;
		if(l>=mid+1) insert(l,r,c,2*k+1);
		else if(r<=mid) insert(l,r,c,2*k);
		else{
			insert(l,mid,c,2*k);
			insert(mid+1,r,c,2*k+1);
		}
	}
}

unsigned query(int l,int r,int k){
	if(l<=a[k].l && a[k].r<=r){
		return a[k].c;
	}else{
		int mid=(a[k].l+a[k].r)/2;
		if(l>=mid+1) return query(l,r,2*k+1);
		else if(r<=mid) return query(l,r,2*k);
		else{
			 return (query(l,mid,2*k)+query(mid+1,r,2*k+1))%yu;
		}
	}
}

void initial(){
	mp.clear();
	build(1,n,1);
}

void input(){
	int cnt=1;
	map <unsigned int,int>::iterator it;
	for(int i=1;i<=n;i++){
		scanf("%d",&data[i]);
		mp[data[i]]=0;
	}
	for(it=mp.begin();it!=mp.end();it++){
		it->second=cnt++;
	}
}

void computing(){
	int ans=0,tmp,pos;
	for(int i=1;i<=n;i++){
		pos=mp[data[i]];
		tmp=query(1,pos,1)+1;
		ans=(ans+tmp)%yu;
		insert(pos,pos,tmp,1);
	}
	cout<<ans<<endl;
}

int main(){
	while(scanf("%d",&n)!=EOF){
		initial();
		input();
		computing();
	}
	return 0;
}


 

 

 

posted @ 2013-09-01 19:47  Class Xman  阅读(131)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3