luogu P6564 [POI2007] 堆积木KLO 树状数组+dp
#include<bits/stdc++.h> using namespace std; const int N=1e6+10; int a[N]; int n; int tr[N]; int f[N]; int ans; int lowbit(int x) { return x&-x; } void add(int x, int c) { for (int i = x; i <= n; i += lowbit(i)) tr[i] =max(c,tr[i]); } int query(int x) { int res = 0; for (int i = x; i; i -= lowbit(i)) res =max(res,tr[i]); return res; } struct node { int v; int id; } e[N]; //f[i]=max(f[j])+1 //j<i //v[j]<v[i] //v[i]-v[j]<=i-j j-v[j]<=i-v[i] //也就是按 j-v[j]<=i-v[i] 排序的最长上升序列 //用树状数组维护 bool cmp(node a,node b) { if(a.id-a.v!=b.id-b.v) return a.id-a.v<b.id-b.v; return a.id<b.id; } int main() { cin>>n; for(int i=1; i<=n; i++) { cin>>e[i].v; e[i].id=i; } sort(e+1,e+1+n,cmp); for(int i=1; i<=n; i++) { if(e[i].id-e[i].v<0) continue; f[i]=query(e[i].v-1) + 1; add(e[i].v,f[i]); ans=max(ans,f[i]); } cout<<ans<<endl; return 0; }