题意:现有一段排列,给你部分元素的右边第一个大于他的元素的位置。还原这段序列,输出其中一种合法情况或者-1
-
第一眼看题,明显是一个建图topo的
傻逼题。 -
但是问题来了,按照本题目的的输入方法每次需要对一段区间的点的对某个点连边。
-
脑抽一下就能想到这,裸着建边的话,边数级别是的,看一眼数据范围,建图的时候就已经gg了。
-
既然是对区间连边,那么我们又很容易的想到用选段树来维护线段。
-
先在线段树上父节点向子节点连边,然后维护的时候。
-
我们只要向父节点连边就相当于向子节点间接连了一条边。
-
然后边的级别就能压到级别了。
-
然后回到第一点划线部分。
#include<algorithm>
#include<vector>
#include<iostream>
#include<math.h>
#include<cstring>
#include<string>
#include<stack>
#include<map>
#include<set>
#include<unordered_map>
#include<queue>
#define qcin; ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define pb push_back
#define clr(x) memset(x,0,sizeof x)
#define fmax(x) memset(x,0x3f,sizeof x)
#define finit(x) memset(x,-1,sizeof x)
#define dis(l,r) r-l+1
#define gstr(str) scanf("%s",str)
#define glen(str) strlen(str)
using namespace std;
typedef long long ll;
typedef pair<ll,ll>pll;
const int maxn = 2e6+10;
typedef int arr[maxn];
typedef char str[maxn];
void file(int x){if(x&&fopen("123.in","r")){freopen("123.in","r",stdin);}}
struct node{
int nx,to;
}E[10*maxn];
int id[maxn],ans[maxn],in[maxn],head[maxn],iid[maxn];
int tot,res;
int n,x,t;
void addE(int u,int v){
E[tot]=node{head[u],v};
head[u]=tot++;
in[v]++;
}
void build(int p,int l,int r){
head[p]=-1;in[p]=iid[p]=0;
if(l==r){
id[l]=p;iid[p]=r;
return;
}
int md=(l+r)>>1;
build(p<<1,l,md);
build(p<<1|1,md+1,r);
addE(p<<1,p),addE(p<<1|1,p);
}
void upd(int p,int l,int r,int ql,int qr,int k){
if(ql>qr)return;
if(ql<=l&&r<=qr){
addE(p,k);
return;
}
int md=(l+r)>>1;
if(ql<=md)upd(p<<1,l,md,ql,qr,k);
if(qr>md)upd(p<<1|1,md+1,r,ql,qr,k);
}
int main(){
//file(1);
for(scanf("%d",&t);t--;){
scanf("%d",&n);
tot=0;res=0;
build(1,1,n);
for(int i=1;i<=n;i++){
scanf("%d",&x);
if(~x){
upd(1,1,n,i+1,x-1,id[i]);
if(x<=n)upd(1,1,n,i,i,id[x]);
}
}
queue<int>Q;
for(int i=1;i<=n;i++)if(!in[id[i]])Q.push(id[i]);
while(Q.size()){
int u=Q.front();
Q.pop();
if(iid[u])ans[iid[u]]=++res;
for(int i=head[u];~i;i=E[i].nx){
int v=E[i].to;
in[v]--;
if(!in[v])Q.push(v);
}
}
if(res!=n)puts("-1");
else{
for(int i=1;i<=n;i++){
printf("%d%c",ans[i],i==n?'\n':' ');
}
}
}
return 0;
}