hdu 4521 小明系列问题——小明序列(线段树)


#include<stdio.h>
#include<string.h>
 int A[110000],sum[410000]; int Max(int a,int b){return a<b?b:a;} void update(int i,int l,int r,int p,int v) { int mid;
    sum[i]=Max(sum[i],v); if(l==r) return ; 
    mid=(l+r)/2; if(p<=mid) update(i<<1,l,mid,p,v); else update(i<<1|1,mid+1,r,p,v); } int query(int i,int l,int r,int a,int b) { int mid; if(a>b) return 0; if(l==a&&r==b) return sum[i];
    mid=(l+r)/2; if(b<=mid) return query(i<<1,l,mid,a,b); if(a>mid) return query(i<<1|1,mid+1,r,a,b); return Max(query(i<<1,l,mid,a,mid),query(i<<1|1,mid+1,r,mid+1,b)); } int dp[110000]; int main() { int n,d,i,ans; while(scanf("%d%d",&n,&d)!=EOF) {
        memset(sum,0,sizeof(sum)); for(i=1;i<=n;i++)
            scanf("%d",&A[i]);
        ans=0; for(i=1;i<=n;i++) { if(i>d+1)
                update(1,1,100000 + 5,A[i-d-1] + 1,dp[i-d-1]);
            dp[i]=query(1,1,100000 + 5,1,A[i])+1;
            ans=Max(ans,dp[i]); }
        printf("%d\n",ans); } return 0; } 版本二: 
#include <stdio.h>  
#include <string.h>  
#define MAXN 100010  
#define MAXE 400010  
const int INF = 0x3f3f3f3f;  
struct Node{
	int l,r;
	int max;
}node[MAXE];
int data[MAXN];
int ans[MAXN];
void inite(int root, int l, int r)
{
	node[root].l =l, node[root].r = r;
	node[root].max = 0;
	if(l == r) return ;
	int mid = (l + r) >> 1;
	inite(2 * root, l, mid);
	inite(2 * root + 1, mid + 1, r);
	return ;
}
int query(int root, int pos)
{
	if(node[root].l == node[root].r) return node[root].max;
	int mid = (node[root].l + node[root].r) >> 1;
	if(pos <= mid)
		return query(2 * root, pos);
	int temp = query(2 * root + 1, pos);
	return (temp > node[2 * root].max) ? temp : node[2 * root].max;
}
void insert(int root, int pos, int num)
{
	if(node[root].max < num) node[root].max = num;
	if(node[root].l == node[root].r) return ;
	int mid = (node[root].l + node[root].r) >> 1;
	if(pos <= mid)
		insert(2 * root, pos, num);
	else
		insert(2 * root + 1, pos, num);
}
int main()
{
	int n, d;
	while(~scanf("%d%d", &n, &d))
	{
		int max = 1;
		for(int i = 0; i < n; ++i)
		{
			scanf("%d", &data[i]);
			++data[i];
		}
		inite(1, 0, MAXN);

		for(int i = 0; i < d; ++i)ans[i] = 1;
		for(int i = 0; i < n; ++i)
		{
			if(i - d >= 0)
			{
				ans[i] =1 + query(1, data[i] - 1);
				if(ans[i] > max) max = ans[i];
				insert(1, data[i - d], ans[i - d]);
			}
		}
		printf("%d\n", max);
	}
	return 0;
}


你可能感兴趣的:(hdu 4521 小明系列问题——小明序列(线段树))