理解置换的概念以及题意后,剩下的就是模拟了。
花了挺长时间,主要是模拟有漏洞+想暴力过。
希望自己能养成一个做题目的好习惯,虽然写完代码再来debug能比较稳定地查出错误,但是一旦出现了整体性的解法错误就得推倒重来,这会花掉非常多的时间,希望自己能权衡一下写代码和想明白之间的时间分配,任何基本功都是值得坚持训练的。
代码
#include<stdio.h>
#include<algorithm>
#define m ((l+r)>>1)
#define ls (now<<1)
#define rs (ls|1)
using namespace std;
const int maxn = 100010;
int n;
int a[maxn];
int p[maxn];
int bar[maxn];
int nex[maxn];
int MAXBAR;
int tree1[maxn<<2][2];
int tree2[maxn<<2];
void maintain2(int now)
{
tree2[now]=max(tree2[ls],tree2[rs]);
}
void build(int l,int r,int now)
{
tree1[now][0]=tree1[now][1]=0;
if(l==r)
{
tree2[now]=a[l];
return;
}
build(l,m,ls);
build(m+1,r,rs);
maintain2(now);
}
void pushdown1(int now)
{
tree1[ls][1]=max(tree1[ls][1],tree1[now][1]);
tree1[rs][1]=max(tree1[rs][1],tree1[now][1]);
tree1[ls][0]=max(tree1[ls][0],tree1[ls][1]);
tree1[rs][0]=max(tree1[rs][0],tree1[rs][1]);
}
void update1(int l,int r,int now,int ql,int qr,int val)
{
if(l>qr||r<ql) return;
if(ql<=l&&r<=qr)
{
tree1[now][0]=max(tree1[now][0],val);
tree1[now][1]=max(tree1[now][1],val);
return;
}
pushdown1(now);
update1(l,m,ls,ql,qr,val);
update1(m+1,r,rs,ql,qr,val);
}
int qry1(int l,int r,int now,int pos)
{
if(l==r) return tree1[now][0];
pushdown1(now);
if(pos<=m) return qry1(l,m,ls,pos);
else return qry1(m+1,r,rs,pos);
}
void update2(int l,int r,int now,int pos)
{
if(l==r)
{
tree2[now]=0;
return;
}
if(pos<=m) update2(l,m,ls,pos);
else update2(m+1,r,rs,pos);
maintain2(now);
}
int qry2(int l,int r,int now,int ql,int qr)
{
if(l>qr||r<ql) return 0;
if(ql<=l&&r<=qr) return tree2[now];
return max(qry2(l,m,ls,ql,qr),qry2(m+1,r,rs,ql,qr));
}
void init()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",a+i);
p[a[i]]=i;
bar[i]=0;
nex[i]=0;
}
MAXBAR=0;
build(1,n,1);
}
int GETMAX(int pos)
{
int L = qry1(1,n,1,pos);
return qry2(1,n,1,L+1,pos);
}
void add(int L,int R)
{
for(int i=0;i<R-L+1;i++)
{
int j = (i+1)%(R-L+1);
bar[L+i]=-1;
nex[a[i+L]]=a[j+L];
}
MAXBAR=max(MAXBAR,R);
update1(1,n,1,R+1,n,R);
bar[R]=1;
bar[L-1]=1;
}
void print()
{
for(int i=1;i<=n;i++) printf("%d%c",nex[i],i==n?'\n':' ');
}
void solve()
{
init();
for(int i=1;i<=n;i++) if(!nex[i])
{
a[n+1]=a[MAXBAR+1];
int PMAX = GETMAX(p[i]);
int NMAX = bar[p[i]]==1?0:a[p[i]+1];
if(PMAX>=NMAX) add(p[PMAX],p[i]);
else
{
update2(1,n,1,p[i]+1);
bar[p[i]]=-1;
nex[i]=a[p[i]+1];
}
}
print();
}
int main()
{
int T;
scanf("%d",&T);
while(T--) solve();
return 0;
}