这类操作构造问题一般给的操作限制就是上界。
也就是我们要n次换完。很容易想到一次换一个。
由于是反转操作,我们可以i和n-i+1打包一起换。
然后换n/2次即可。
细节见代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define re register
#define ls (o<<1)
#define rs (o<<1|1)
//#define m (l+r)/2
#define pb push_back
typedef pair<int,int> pii;
const double PI= acos(-1.0);
const int M = 1e5+7;
/*
int head[M],cnt=1;
void init(int n){cnt=1;for(int i=0;i<=n;i++)head[i]=0;}
struct EDGE{int to,nxt,w;}ee[M*2];
void add(int x,int y,int w){ee[++cnt].nxt=head[x],ee[cnt].w=w,ee[cnt].to=y,head[x]=cnt;}
*/
vector<int>v[M];int sz=0,N;
int id[M];//数字i的下标
int a[M],b[M];
void gao(int sz){
int tp=1,n=v[sz].size();
int L=0,R=N+1;
int bl=0,br=N+1;
for(int i=0;i<n/2;i++){
int nml=v[sz][i],nmr=v[sz][n-i-1];
// cout<<sz<<" - "<<nml<<" "<<nmr<<" "<<n<<endl;
for(int j=R-nml;j<R;j++){
b[j]=a[L+j-(R-nml)+1];
// cout<<j<<" - > "<<L+j-(R-nml)+1<<endl;
}
for(int j=L+1;j<=L+nmr;j++){
b[j]=a[R-nmr+(j-L-1)];
// cout<<j<<" - > "<<R-nmr+(j-L-1)<<endl;
}
L+=nml,R-=nmr;
bl+=nmr,br-=nml;
}
if(n&1){
int nml=v[sz][n/2],nmr=v[sz][n/2];
for(int i=bl+1;i<=br-1;i++)b[i]=a[L+i-bl];
}
for(int i=1;i<=N;i++){
a[i]=b[i];
id[a[i]]=i;
}
// cout<<" -- ";for(int j=1;j<=N;j++)cout<<a[j]<<" ";cout<<endl;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int n,q;
cin>>n;
N=n;
for(int i=1;i<=n;i++){
cin>>a[i];
id[a[i]]=i;
}
//每次把i和 n-i移动到对应位置,每次移动2个,就不用考虑奇偶对称的问题了
for(int i=1;i<=n/2;i++){
/* 把a->A ,b -> B
情况一: XAXaXbXBX
1:
X AXa X bXB X
X bXB X AXa X
2:
X b XBXAX a X
X a XBXAX b X
情况二: XAXbXaXBX
1:
X1 AXb X aXB X2
X2 aXB X AXb X1
2:
X1 aXBXAXb X2
*/
int ia=id[i],ib=id[n-i+1];
if(ia==i&&ib==n-i+1)continue;
// cout<<i<<" -=-=-= "<<endl;
// cout<<" == == "<<ia<<" "<<ib<<endl;
if(ia<ib){//对应情况一
//步数一:
++sz;
if(i-1>0)v[sz].pb(i-1);//当i>1时才有最左边的块
v[sz].pb(ia-i+1);
if(ib-ia-1>0)v[sz].pb(ib-ia-1);
v[sz].pb(n-i+1-ib+1);
if(i-1>0)v[sz].pb(i-1);
/*步数二:
X b XBXAX a X
X a XBXAX b X
*/
gao(sz);//更新变化
if(v[sz].size()==1)v[sz].clear(),--sz;//不需要这一步
++sz;
if(i-1>0)v[sz].pb(i-1);
v[sz].pb(1);
if(n-i+1-i-1>0)v[sz].pb(n-i+1-i-1);
v[sz].pb(1);
if(i-1>0)v[sz].pb(i-1);
gao(sz);//更新变化
if(v[sz].size()==1)v[sz].clear(),--sz;//不需要这一步
}else{//对应i情况二
/*
情况二: XAXbXaXBX
1:
X AXb X aXB X
X aXB X AXb X
2:
X1 aXBXAXb X2
*/
++sz;
if(i-1>0)v[sz].pb(i-1);
v[sz].pb(ib-i+1);
if(ia-ib-1>0)v[sz].pb(ia-ib-1);
v[sz].pb(n-i+1-ia+1);
if(i-1>0)v[sz].pb(i-1);
gao(sz);//更新变化
if(v[sz].size()==1)v[sz].clear(),--sz;//不需要这一步
++sz;
if(i-1>0)v[sz].pb(i-1);
v[sz].pb(n-i+1-i+1);
if(i-1>0)v[sz].pb(i-1);
gao(sz);
if(v[sz].size()==1)v[sz].clear(),--sz;//不需要这一步
}
//cout<<" -- ";for(int j=1;j<=n;j++)cout<<a[i]<<" ";cout<<endl;
}
cout<<sz<<endl;
for(int i=1;i<=sz;i++){
cout<<v[i].size()<<" ";
for(auto y:v[i]){
cout<<y<<" ";
}
cout<<endl;
}
return 0;
}