P10033 题解

· · 题解

原题链接

一个新思路。看了其他题(乱)解(搞),感觉其实挺神秘的,我没想到这样就过了。所以提供一个从函数的角度的思路。

先把 n=2n=3 特判掉,暴力即可。

由于后续思路涉及取模,所以不妨设 permutation 的值域为 [0,n)

我们记 A=n-1,B=n-2,即最大和次大。

考虑所有的数字都等于 A,只有 A 改为 B,此时要求 AB 不相邻即可。

我们于是转手考虑 AB 相邻的情况。

考虑模 n 意义下函数 f(x) = x+1 直接使用此函数不行,全局的 sum 有问题,但是局部的 sum 一定没有问题,可以在模 n 意义下证明这里局部的 sum 不相等。

现在我们考虑把其中的少量的数字再加一来克服这个问题。

考虑 AB 的位置,分 3 类:

任何情况都可以归约到上面(如果不行就把 p 翻转一下)

做法核心在于,使用模 n 进行必要性探路,在不合法处再调整并说明。事实上,在其他题你可以看见类似的 trick。

参考程序:

/* Code by pp_orange */
//#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define m_p(a,b) make_pair(a,b)
#define pb push_back
#define ll long long
#define ull unsigned long long
#define ld long double
#define inf 0x7FFFFFFF
#define inff 9223372036854775807
#define rep(i,l,r) for(int i=l;i<r;++i)
#define repp(i,l,r) for(int i=l;i<=r;++i)
#define per(i,r,l) for(int i=r-1;i>=l;--i)
#define pper(i,r,l) for(int i=r;i>=l;--i)
#define pii pair<int,int>
#define fi first
#define se second
#define p_q priority_queue
#define all(x) x.begin(),x.end()
#define rall(x) x.rbegin(),x.rend()
#define ls(x) ((x)<<1)
#define rs(x) ((x)<<1|1)
#define lb(x) ((x)&-(x))
const int mod = 998244353;
//#define int ll
using namespace std;
namespace FastIO {
    const int SZ=(1<<21)+1;
    struct I {
        char ibuf[SZ],*iS,*iT,c;int f,_eof;FILE*fi;
        I(FILE*f):fi(f){}
        inline char Gc(){return iS==iT?(iT=(iS=ibuf)+fread(ibuf,1,SZ,fi),(iS==iT?EOF:*iS++)):*iS++;}
        inline ll operator()(){ll x;operator()(x);return x;}
        inline I&operator()(char&x){x=Gc();return*this;}
        inline I&operator()(char*s){for(c=Gc();c<32||c>126||c==' ';)c=Gc();for(;c>31&&c<127&&c!=' '&&c!='\n'&&c!='\r';++s,c=Gc())*s=c;*s=0;return*this;}
        template<class T>inline I&operator()(T&x){_eof=0;for(f=1,c=Gc();(c<'0'||c>'9')&&!_eof;c=Gc()){if(c=='-')f=-1;_eof|=c==EOF;}for(x=0;c<='9'&&c>='0'&&!_eof;c=Gc())x=x*10+(c&15),_eof|=c==EOF;x*=f;return*this;}
        template<class T>I&operator()(T*x,const int&n,const int&st=1){rep(i,st,n){operator()(x[i]);}return*this;}
    } rd(stdin);
    struct O {
        char obuf[SZ],*oS=obuf,*oT=oS+SZ-1,qu[55];int f,qr;FILE*fi;
        O(FILE*f):fi(f){}
        ~O(){Flush();}
        inline void Flush(){fwrite(obuf,1,oS-obuf,fi),oS=obuf;}
        inline O&operator()(char x){*oS++=x;if(oS==oT)Flush();return*this;}
        inline O&operator()(char*s){int len=strlen(s);for(f=0;f<len;++f)operator()(s[f]);return*this;}
        inline O&operator()(const char*s){return operator()((char*)s);}
        template<class T>inline O&operator()(T x){if(!x)operator()('0');if(x<0)operator()('-'),x=-x;while(x)qu[++qr]=x%10+'0',x/=10;while(qr)operator()(qu[qr--]);return*this;}
        template<class T>O&operator()(T*x,const int&n,const char&ed=' ',const int&st=1){rep(i,st,n)operator()(x[i])(ed);return*this;}
    } out(stdout);
}
using namespace FastIO;
#define MAX 1000005
int a[MAX];
signed main(){
    //freopen("in.in","r",stdin);
    //freopen("out.out","w",stdout);
    int T = rd();
    while(T--){
        int n = rd();
        repp(i,1,n)a[i] = rd();
        if(n==2){
            out(-1)('\n');
        }else if(n==3){//暴力
            bool flag = 0;
            repp(i,1,3){
                if(i==a[1])continue;
                repp(j,1,3){
                    if(j==a[2])continue;
                    repp(k,1,3){
                        if(k==a[3])continue;
                        if(i+j!=a[1]+a[2]&&j+k!=a[2]+a[3]&&i+j+k!=6){
                            out(i)(' ')(j)(' ')(k)('\n');
                            flag = 1;
                            break;
                        }
                    }
                    if(flag)break;
                }
                if(flag)break;
            }
            if(!flag)out(-1)('\n');
        }else{
            int n1,n2;
            repp(i,1,n){
                if(a[i]==n)n1 = i;
                if(a[i]==n-1)n2 = i;
            }
            if(abs(n1-n2)!=1){//相邻
                repp(i,1,n){
                    if(a[i]==n)out(n-1)(' ');
                    else out(n)(' ');
                }out('\n');
            }else{
                if(n1==1||n1==n){//第三类
                    repp(i,1,n){
                        if(i==n2||i==n+1-n1){
                            out((a[i]+1)%n+1)(' ');
                        }else{
                            out((a[i]%n)+1)(' ');
                        }
                    }out('\n');
                }else if(n2==1||n2==n){//第二类
                    repp(i,1,n){
                        if(i==n2){
                            out((a[i]+1)%n+1)(' ');
                        }else{
                            out((a[i]%n)+1)(' ');
                        }
                    }out('\n');
                }else{//第一类
                    repp(i,1,n){
                        if(i==n1||i==n2){
                            out((a[i]+1)%n+1)(' ');
                        }else{
                            out((a[i]%n)+1)(' ');
                        }
                    }out('\n');
                }
            }
        }
    }
    return 0;
}