• Codeforces474E


    Portal

    Description

    给出一个(n(nleq10^5))的正整数序列({a_n}(a_ileq10^{15}))和正整数(d(dleq10^9)),求({a_n})的一个子序列({b_m}),使得(forall iin[1,m-1],|b_i-b_{i-1}|geq d)

    Solution

    跟求最长上升子序列的方法差不多。(f[i])表示目前以数值(i)结尾的满足要求的序列长度,则:

    [ f[i]=max{f[j]}+1 quad (jleq i-d vee jgeq i+d) $$因为$a_i$比较大,所以先离散化一波。离散化之后求$jleq i-d vee jgeq i+d$时,二分一下即可,不会增加复杂度。可以用树状数组来维护$f[i]$的前缀与后缀,不过我很懒就写了线段树。 > 时间复杂度$O(nlogn)$。 ##Code ```cpp //Pillars #include <algorithm> #include <cstdio> #include <queue> using namespace std; typedef long long lint; typedef std::pair<lint,int> pairI; inline char gc() { static char now[1<<16],*s,*t; if(s==t) {t=(s=now)+fread(now,1,1<<16,stdin); if(s==t) return EOF;} return *s++; } inline lint read() { lint x=0; char ch=gc(); while(ch<'0'||'9'<ch) ch=gc(); while('0'<=ch&&ch<='9') x=x*10+ch-'0',ch=gc(); return x; } int const N=2e5+10; int n,d,n0; lint h[N],map[N]; int rt,cnt,ch[N][2]; pairI maxV[N]; void update(int p) {maxV[p]=max(maxV[ch[p][0]],maxV[ch[p][1]]);} lint L,R; void ins(int p,lint L0,lint R0,pairI x) { if(L==L0&&R0==L) {maxV[p]=x; return;} for(int i=0;i<2;i++) if(!ch[p][i]) ch[p][i]=++cnt; lint mid=L0+R0>>1; if(L<=mid) ins(ch[p][0],L0,mid,x); else ins(ch[p][1],mid+1,R0,x); update(p); } pairI query(int p,lint L0,lint R0) { if(L<=L0&&R0<=R) return maxV[p]; for(int i=0;i<2;i++) if(!ch[p][i]) ch[p][i]=++cnt; lint mid=L0+R0>>1; pairI r=pairI(0,0); if(L<=mid) r=max(r,query(ch[p][0],L0,mid)); if(mid<R) r=max(r,query(ch[p][1],mid+1,R0)); return r; } int ans,seq[N],pre[N]; int main() { n=read(),d=read(); for(int i=1;i<=n;i++) map[i]=h[i]=read(); sort(map+1,map+n+1); n0=unique(map+1,map+n+1)-map-1; for(int i=1;i<=n;i++) h[i]=lower_bound(map+1,map+n0+1,h[i])-map; rt=++cnt; for(int i=1;i<=n;i++) { int x=upper_bound(map+1,map+n0+1,map[h[i]]-d)-map-1; int y=lower_bound(map+1,map+n0+1,map[h[i]]+d)-map; int len=0; pairI t=pairI(0,0); L=1,R=x; if(L<=R) t=query(rt,1,n0); if(t.first>len) len=t.first,pre[i]=t.second; L=y,R=n0; if(L<=R) t=query(rt,1,n0); if(t.first>len) len=t.first,pre[i]=t.second; L=h[i],ins(rt,1,n0,pairI(len+1,i)); } L=1,R=n0; pairI t=query(rt,1,n0); ans=t.first; printf("%d ",ans); for(int i=ans,x=t.second;i>=1;i--,x=pre[x]) seq[i]=x; for(int i=1;i<=ans;i++) printf("%d ",seq[i]); puts(""); return 0; } ``` ##P.S. 老师留的那天忘记写了...真是怠惰啊 一开始懒到不想写离散化于是开了个$10^{15}$的动态开点线段树,结果`MLE`了。]

  • 相关阅读:
    Nacos系列:基于Nacos的配置中心
    Nacos系列:基于Nacos的注册中心
    Nacos系列:欢迎来到Nacos的世界!
    Go语言学习笔记说明
    Hive基础之Hive数据类型
    Go语言学习笔记(六) [包]
    Go语言学习笔记(五) [函数]
    Go语言学习笔记(四) [array、slice、map]
    Go语言学习笔记(三) [控制结构、内建函数]
    git管理多个github账号
  • 原文地址:https://www.cnblogs.com/VisJiao/p/Cf474E.html
Copyright © 2020-2023  润新知