• 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<<"
    ";
    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 }
  • 相关阅读:
    loj10008家庭作业
    loj10006数列分段
    loj10005数列极差
    loj10004智力大冲浪
    codevs 1996 矿场搭建
    11.3 上午考试
    11.2 晚上考试
    11.2 下午考试
    11.2 上午考试
    11.1 下午考试
  • 原文地址:https://www.cnblogs.com/dd-bond/p/10859864.html
Copyright © 2020-2023  润新知