zoj3349

 1 /*

 2 题意:给你n的序列求最长子序列,该序列里|a[i]-a[i-1]|<=d

 3 

 4 分析:O(n^2)的DP很容易想到,那么显然优化也很容易想到

 5 用线段树维护区间最大值,

 6 设dp[i]表示以数值为i结尾的最长符合要求序列,

 7 对于a[i],询问值为[a[i]-d,a[i]+d]的最大值,然后在单点更新;

 8 注意要先离散;

 9  

10  

11  

12 */

13 

14 #include<cstdio>

15 #include<cstring>

16 #include<cstdlib>

17 #include<iostream>

18 #include<cmath>

19 #include<algorithm>

20 #include<vector>

21 #define lson l,m,rt<<1

22 #define rson m+1,r,rt<<1|1

23 using namespace std;

24 const int N=100000+10;

25 int mx[N<<2];

26 vector<int> X;

27 int n,d,n1;

28 int a[N];

29 void init(){

30     sort(X.begin(),X.end());

31     n1=unique(X.begin(),X.end())-X.begin(); 

32 }

33 void pushup(int rt){

34     mx[rt]=max(mx[rt<<1],mx[rt<<1|1]);

35 }

36 void update(int L,int v,int l,int r,int rt){

37     if (l==r){

38         if(v>mx[rt]) mx[rt]=v;

39         return;

40     }

41     int m=(l+r)>>1;

42     if (L<=m) update(L,v,lson);

43     else update(L,v,rson);

44     pushup(rt);

45 } 

46 int query(int L,int R,int l,int r,int rt){

47     if (L<=l && r<=R){

48         return mx[rt];

49     }

50     int m=(l+r)>>1;

51     int t1=0,t2=0;

52     if (L<=m) t1=query(L,R,lson);

53     if (m< R) t2=query(L,R,rson);

54     return max(t1,t2);

55 }

56 void work(){

57     memset(mx,0,sizeof(mx));

58     int ret=0;

59     int t=lower_bound(X.begin(),X.begin()+n1,a[0])-X.begin();

60     update(t,1,0,N-1,1);

61     for (int i=1;i<n;i++){

62         int l=lower_bound(X.begin(),X.begin()+n1,a[i]-d)-X.begin();

63         int r=upper_bound(X.begin(),X.begin()+n1,a[i]+d)-X.begin()-1;

64     //    cout<<i<<" "<<l<<" "<<r<<" ";

65         int t=query(l,r,0,N-1,1);

66     //    cout<<t<<endl;

67         if (t+1>ret) ret=t+1;

68         int c=lower_bound(X.begin(),X.begin()+n1,a[i])-X.begin();

69         update(c,t+1,0,N-1,1);

70     }

71     printf("%d\n",ret);

72 }

73 int main(){

74     while (~scanf("%d%d",&n,&d)){

75         X.clear();

76         for (int i=0;i<n;i++){

77             scanf("%d",&a[i]);

78             X.push_back(a[i]);

79         }

80         init();

81         work();

82     }

83     return 0;

84 }

 

你可能感兴趣的:(ZOJ)