树状数组优化最长上升子序列
最长上升子序列比较暴力的写法是n2 的,实际上我们求得就是前面的比当前小的最长上升子序列的最大值;
树状数组可以优化它;
倒过来求就是最长下降子序列;
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn=1e5+10; typedef double dd; typedef long long ll; ll n; ll a[maxn]; ll id[maxn]; ll f[maxn],g[maxn]; ll b1[maxn],b2[maxn]; int len; ll query_front(int x) { ll ans=0; for(;x;x-=x&(-x)) ans=max(b1[x],ans); return ans; } ll query_back(int x) { ll ans=0; for(;x;x-=x&(-x)) ans=max(b2[x],ans); return ans; } void add_front(int x,ll y) { for(;x<=len;x+=x&(-x)) b1[x]=max(b1[x],y); } void add_back(int x,ll y) { for(;x<=len;x+=x&(-x)) b2[x]=max(b2[x],y); } dd ans; int qw[maxn]; int main() { scanf("%lld",&n); for(int i=1;i<=n;i++) { scanf("%lld",&a[i]); id[i]=a[i]; } sort(id+1,id+n+1); len=unique(id+1,id+n+1)-id-1; for(int i=1;i<=n;i++) qw[i]=lower_bound(id+1,id+len+1,a[i])-id; for(int i=1;i<=n;i++) { f[i]=query_front(qw[i]-1)+a[i]; g[n-i+1]=query_back(qw[n-i+1]-1)+a[n-i+1]; add_front(qw[i],f[i]); add_back(qw[n-i+1],g[n-i+1]); } return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步