诶呦
我就傻了
我们对于每个点其实最多只用连两条边就可以了
而拓扑排序是O(M)的
所以我们就直接瞎搞啦
然而我刚开始想不出来怎么瞎搞QAQ
就很菜
#include<cstdio>
#include<cstring>
inline int read()
{
int ans=0;char t=getchar();
while(t<'0'||t>'9') t=getchar();
while(t>='0'&&t<='9') ans=ans*10+t-'0',t=getchar();
return ans;
}
const int N=1e5+27;
struct node
{
int to,next;
}e[2*N];
int first[N];
int cnt;
int cd[N];
void insert(int u,int v)
{
e[++cnt]=(node){v,first[u]};first[u]=cnt;
cd[v]++;
}
int qu[N+7];
int a[N],ans[N];
int ls[N];
int main()
{
freopen("search.in","r",stdin);
freopen("search.out","w",stdout);
int time=read();
while(time--)
{
memset(first,0,sizeof(first));
memset(cd,0,sizeof(cd));
memset(ls,0,sizeof(ls));
int n=read();
for(int i=1;i<=n;i++) a[i]=read();
cnt=0;
bool tag=1;
for(int i=1;i<=n&&tag;i++)
{
if(ls[a[i]-1]) insert(i,ls[a[i]-1]);
else if(a[i]!=1) printf("No\n"),tag=0;
if(ls[a[i]]) insert(ls[a[i]],i);
ls[a[i]]=i;
}
if(!tag) continue;
int head=1,tail=2;
cnt=n;
for(int i=1;i<=n;i++) if(!cd[i]) qu[tail++]=i,ans[i]=cnt--;
while(head!=tail)
{
int rr=qu[head++];if(head==N) head=0;
for(int k=first[rr];k;k=e[k].next)
if(!--cd[e[k].to]){
ans[e[k].to]=cnt--;qu[tail++]=e[k].to;if(tail==N)tail=0;
}
}
for(int i=1;i<=n;i++) printf("%d ",ans[i]);
printf("\n");
}
fclose(stdin);
fclose(stdout);
return 0;
}