如果直接暴力肯定是不能过的,时间超限,删除一个数,只会影响到这个数的前一个和后一个,用数组模拟链表,如果每次删除后再从头遍历,就是暴力,超时的,所以用set存储删除的数x的前一个,链表的前一个,不是直接前一个数。因为是按顺序来的,不存在存进set然后在删除的情况(这一句,如果看不懂可以忽略)。如果删除n个数复杂度就是o(n)*lg(n),因为set存储是o(n)*lg(n)。
#include <bits\stdc++.h>
using namespace std;
set<int>st;
vector<int>vec;
const int maxn=1e5+7;
int pre[maxn],nxt[maxn],val[maxn],dl[maxn];
int main()
{
int t,n;
scanf("%d",&t);
while(t--)
{
memset(dl,0,sizeof(dl));
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&val[i]);
pre[i]=i-1;
nxt[i]=i+1;
st.insert(i);
}
nxt[0]=1;
pre[n+1]=n;val[n+1]=maxn;
int pre1,nxt1;
while(st.size()>0)
{
vec.clear();
for(auto &x:st)
{
pre1=pre[x];nxt1=nxt[x];
if(val[pre1]>val[x])vec.push_back(pre1),vec.push_back(x);
if(val[x]>val[nxt1])vec.push_back(x),vec.push_back(nxt1);
}
st.clear();
for(auto &x:vec)
if(!dl[x])
{
pre1=pre[x];nxt1=nxt[x];
nxt[pre1]=nxt1;
pre[nxt1]=pre1;
st.insert(pre1);
dl[x]=1;
}
}
int cnt=0;
for(int i=nxt[0];i!=n+1;i=nxt[i])
cnt++;
printf("%d\n",cnt);
for(int i=nxt[0];i!=n+1;i=nxt[i])printf("%d ",val[i]);
puts("");
}
return 0;
}
/*
2
8
1 4 5 2 3 2 1 2
6
1 4 5 2 3 2
*/