先附一篇以前的文章链接:https://blog.csdn.net/PWeiDa/article/details/82226758
现在来补一下这题的树状数组方法
有可能有人不是很明白树状数组的原理,今天找到一篇大佬写的通俗易懂的博客,给个链接
大佬博客:https://www.cnblogs.com/acgoto/p/8583952.html#4044998
现在明白树状数组了,再来看看怎么运用在这题上,这题是为了求最长上升子序列和最长不上升子序列,最重要的就是快速维护栈中数据,所以可以用树状数组来存数据,不过和之前存系统高度不一样,这里存的是在每个导弹被拦截时的最长长度
代码如下:
#include <iostream>
#include <string.h>
#include <string>
#include <algorithm>
#include <stdio.h>
#include <math.h>
#include <stack>
#include <queue>
#include <sstream>
#include <vector>
#include <set>
using namespace std;
int f[100005],a[100005];
int maxn;
int lowbit(int x)
{
return x&(-x);
}
void add(int x,int u)
{
for(int i=x;i<=maxn;i+=lowbit(i))
f[i]=max(f[i],u);
}
int find(int x)
{
int ans=0;
for(int i=x;i>=1;i-=lowbit(i))
ans=max(ans,f[i]);
return ans;
}
int main()
{
int n=0;
maxn=0;
while(scanf("%d",&a[++n])!=EOF)
{
maxn=max(maxn,a[n]);
}
n--;
int ans1=0,ans2=0;
for(int i=n;i>=1;i--)
{
int u=find(a[i])+1;//这里是大于
add(a[i],u);
ans1=max(ans1,u);
}
memset(f,0,sizeof(f));
for(int i=1;i<=n;i++)
{
int u=find(a[i]-1)+1;//这里是小于,不能等于,原因可以看之前的代码
add(a[i],u);
ans2=max(ans2,u);
}
printf("%d\n",ans1);
printf("%d\n",ans2);
return 0;
}