Codeforces 1159E Permutation recovery(构造+拓扑)
这道题其实只要解决了什么时候输出 -1 ,那么此题的构造方法也就解决了。首先我们可以观察这组 3 3 4 和 3 4 4 ,可以算出第二组是不成立的,在观察一组 2 3 4 5 和 3 2 4 5 ,第二组也是不成立的。我们将 i 和 a[ i ] 视为区间两端点,可以发现只有在任意一对区间不在端点处相交时才会出现 -1 。假设 a[ i-1 ] = x , a[ i ] = y , x < y ,那么可以得出 ans[ i - 1 ] < x , ans[ i ] < y 。若 ans [ i - 1 ] < ans [ i ] ,那么 a[ i - 1 ] 应该等于 i 才对; 若 ans[ i - 1] > ans [ i ] , 又因为 a[ i - 1 ] < x ,那么 a[ i ] 应该等于 x才对,综上所以不成立。接下来考虑 a[ i ]==-1 的时候, 那么此时只需要将 a[ i ] = i + 1 即可,这样保证与之前的区间不在除端点处之外的地方相交了,那么对于这些合法的区间,一定可以构成合法的表达式,那么我们将区间右端点向左端点引出一条边,从 n+1 开始拓扑排序,然后按照当前点连接的所有点按照端点值从小到大以此给大到小的值,这样保证任意两端点不会有额外的一条边产生,跑完后即是合法表达式。
1 // ——By DD_BOND 2 3 //#include<bits/stdc++.h> 4 #include<functional> 5 #include<algorithm> 6 #include<iostream> 7 #include<sstream> 8 #include<iomanip> 9 #include<climits> 10 #include<cstring> 11 #include<cstdlib> 12 #include<cstddef> 13 #include<cstdio> 14 #include<memory> 15 #include<vector> 16 #include<cctype> 17 #include<string> 18 #include<cmath> 19 #include<queue> 20 #include<deque> 21 #include<ctime> 22 #include<stack> 23 #include<map> 24 #include<set> 25 26 #define fi first 27 #define se second 28 #define MP make_pair 29 #define pb push_back 30 #define INF 0x3f3f3f3f 31 #define pi 3.1415926535898 32 #define lowbit(a) (a&(-a)) 33 #define lson l,(l+r)/2,rt<<1 34 #define rson (l+r)/2+1,r,rt<<1|1 35 #define Min(a,b,c) min(a,min(b,c)) 36 #define Max(a,b,c) max(a,max(b,c)) 37 #define debug(x) cerr<<#x<<"="<<x<<"\n"; 38 39 using namespace std; 40 41 typedef long long ll; 42 typedef pair<int,int> P; 43 typedef pair<ll,ll> Pll; 44 typedef unsigned long long ull; 45 46 const int seed=131; 47 const ll LLMAX=2e18; 48 const int MOD=1e9+7; 49 const double eps=1e-8; 50 const int MAXN=1e6+10; 51 const int hmod1=0x48E2DCE7; 52 const int hmod2=0x60000005; 53 54 inline ll sqr(ll x){ return x*x; } 55 inline int sqr(int x){ return x*x; } 56 inline double sqr(double x){ return x*x; } 57 ll gcd(ll a,ll b){ return b==0? a: gcd(b,a%b); } 58 ll exgcd(ll a,ll b,ll &x,ll &y){ ll d; (b==0? (x=1,y=0,d=a): (d=exgcd(b,a%b,y,x),y-=a/b*x)); return d; } 59 ll qpow(ll a,ll n){ll sum=1;while(n){if(n&1)sum=sum*a%MOD;a=a*a%MOD;n>>=1;}return sum;} 60 inline int dcmp(double x){ if(fabs(x)<eps) return 0; return (x>0? 1: -1); } 61 62 vector<int>G[MAXN]; 63 int a[MAXN],ans[MAXN]; 64 65 int main(void) 66 { 67 ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); 68 int T; cin>>T; 69 while(T--){ 70 set<int>s; 71 int n,flag=0; cin>>n; 72 for(int i=1;i<=n;i++) cin>>a[i]; 73 for(int i=1;i<=n;i++){ 74 if(a[i]==-1) a[i]=i+1; 75 while(s.find(i)!=s.end()) s.erase(i); 76 if(!s.empty()&&*s.begin()<a[i]) flag=1; 77 s.insert(a[i]); 78 G[a[i]].pb(i); 79 } 80 if(flag) cout<<-1<<endl; 81 else{ 82 int id=n; 83 queue<int>q; q.push(n+1); 84 while(!q.empty()){ 85 int u=q.front(); q.pop(); 86 for(int i=0;i<(int)G[u].size();i++){ 87 int v=G[u][i]; 88 ans[v]=id--; 89 q.push(v); 90 } 91 } 92 for(int i=1;i<=n;i++) cout<<ans[i]<<' '; 93 cout<<endl; 94 } 95 for(int i=1;i<=n+1;i++) G[i].clear(); 96 } 97 return 0; 98 }