• 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 }
  • 相关阅读:
    10丨应该如何理解请求方法?
    采用镜像的方法安装python第三方库
    09丨HTTP报文是什么样子的?
    Fiddler——Https抓包(十二)
    三基础篇(7讲)08丨键入网址再按下回车,后面究竟发生了什么?
    fiddler-弱网测试(十一)
    python中a+=a与a=a+a的区别
    07 | 自己动手,搭建HTTP实验环境
    Fiddler——断点应用(十)
    【HGOI】物品选取
  • 原文地址:https://www.cnblogs.com/Rlemon/p/3093829.html
Copyright © 2020-2023  润新知