又是模拟赛题,感觉挺牛的。kkio 场了/bx
首先发现每一次大操作等同于进行一次置换,会形成若干个置换环。根据经典结论得,设这些环长为 \(cyc_i\),则有 \(k=\operatorname{lcm}cyc_i\)。于是考虑在原图中构造若干置换环。
然后通过手玩发现,可以在 \(4\) 步以内交换任意两个相邻的数。于是可以把矩阵按照 S 形拉成一条链,再在这条链上割出来若干段作环。
再考虑怎么构造 \(cyc_i\)。因为所有的环长加起来不能超过 \(n\times m\),所以要使 \(\sum cyc_i\) 尽可能小。容易发现,将 \(k\) 分解质因数得到 \(k=\prod p_i^{c_i}\),\(cyc_i\) 取到所有的 \(p_i^{c_i}\),剩下为 \(1\) 时,\(\sum cyc_i\) 最小。
于是将这几个置换环构造出来,就做完了,并不难写。无解的情况就是 \(\sum p_i^{c_i}>n\times m\)。操作不会超过 \(4\times n\times m\) 次。随便过。
code:
点击查看代码
int n,m;ll k;
struct op{
int x,y,k;
op(int _x=0,int _y=0,int _k=0):x(_x),y(_y),k(_k){}
};
vector<op> g;vector<int> p;vector<pii> d;
il void sw1(int x,int y){
g.eb(op(x-1,y,0));
g.eb(op(x-1,y,1));
g.eb(op(x-1,y,1));
g.eb(op(x-1,y,1));
}
il void sw2(int x,int y){
g.eb(op(x,y,1));
g.eb(op(x,y,1));
g.eb(op(x,y,0));
g.eb(op(x,y,1));
}
il void sw3(int x,int y){
g.eb(op(x-1,y-1,0));
g.eb(op(x-1,y-1,0));
g.eb(op(x-1,y-1,1));
}
il void sw4(int x,int y){
g.eb(op(x-1,y,1));
g.eb(op(x-1,y,0));
g.eb(op(x-1,y,1));
g.eb(op(x-1,y,1));
}
void Yorushika(){
scanf("%d%d%lld",&n,&m,&k);
ll sum=0;
for(int i=2;1ll*i*i<=k;i++){
if(k%i==0){
ll cnt=1;
while(k%i==0)k/=i,cnt*=i;
p.eb(cnt),sum+=cnt;
}
}
if(k>1)p.eb(k),sum+=k;
if(sum>n*m)return puts("-1"),void();
drep(i,n,1){
if(i&1)rep(j,1,m)d.eb(Mp(i,j));
else drep(j,m,1)d.eb(Mp(i,j));
}
for(int x:p){
pii lst=Mp(0,0);
rep(i,1,x){
pii j=d.back();d.pop_back();
if(lst.fi){
if(lst.fi!=j.fi){
if(j.se==1)sw4(j.fi,j.se);
else sw3(j.fi,j.se);
}else{
if(j.fi==1)sw2(j.fi,min(lst.se,j.se));
else sw1(j.fi,min(lst.se,j.se));
}
}
lst=j;
}
}
printf("%d\n",(int)g.size());
for(op i:g)printf("%c %d %d\n",!i.k?'T':'R',i.x,i.y);
}
signed main(){
int t=1;
// scanf("%d",&t);
while(t--)
Yorushika();
}