1. 程式人生 > >Codeforces 1159E Permutation recovery(構造+拓撲)

Codeforces 1159E Permutation recovery(構造+拓撲)

\n stack climits rst include fir spa 輸出 ORC

這道題其實只要解決了什麽時候輸出 -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 }

Codeforces 1159E Permutation recovery(構造+拓撲)