这尼玛是真坑啊
求最长递增子序列的nlogn算法需要维护一个辅助数组 我一直以为需要用二分查找维护 结果实际上只需要调用uper_bound这种函数就可以维护 ~~
不知道从哪里弄来的题解感觉像是错的
很明显nlogn的算法保存子序列路径是非常困难的而且就算保存以后求ax的出现次数复杂度也不低啊 所以这个题解的做法我暂时还是想不明白 可能是我未知的什么算法吧 真是弱爆了
这地方理解错了 求重复的意思应不是求路径重复 路径重复是求不出来的 这个结题报告的做法是正确的,但是比较难理解
贴别人代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define MAX 100005
int a[MAX];
int dp[MAX][2];
int asc[MAX];
int desc[MAX];
struct node
{
int id,num;
} data[MAX];
bool cmp(node a,node b)
{
return a.num<b.num;
}
int main()
{
int t,n;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(int i=1; i<=n; i++)
scanf("%d",&a[i]);
int *it;
int al,dl;
al=n,dl=1;
for(int i=n; i>=1; i--)
{
if(al==n)
{
asc[al--]=a[i];
desc[dl++]=a[i];
dp[i][0]=1;
dp[i][1]=1;
continue;
}
if(a[i]<=asc[al+1])
{
asc[al]=a[i];
dp[i][0]=n+1-al;
al--;
}
else
{
it=lower_bound(asc+1+al,asc+n+1,a[i]);
it--;
*it=a[i];
dp[i][0]=asc+n+1-it;
}
if(a[i]>=desc[dl-1])
{
desc[dl]=a[i];
dp[i][1]=dl;
dl++;
}
else
{
it=upper_bound(desc+1,desc+dl,a[i]);
*it=a[i];
dp[i][1]=it-desc;
}
}
for(int i=1; i<=n; i++)
data[i].id=i,data[i].num=a[i];
sort(data+1,data+n+1,cmp);
int tmp=0,ans=0;
int l,r;
l=1;
for(int r=1;r<=n;r++)
{
ans=max(ans,max(dp[r][0],dp[r][1]));
int idx=data[r].id;
while(data[l+1].num<data[r].num)
{
tmp=max(tmp,dp[data[l].id][1]);
l++;
}
ans=max(ans,dp[idx][0]+tmp);
}
printf("%d\n",ans);
}
return 0;
}