首页 > 其他分享 >P7372

P7372

时间:2024-03-09 10:37:52浏览次数:25  
标签:int void eb P7372 fi se op

又是模拟赛题,感觉挺牛的。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();
}

标签:int,void,eb,P7372,fi,se,op
From: https://www.cnblogs.com/yinhee/p/18062332/P7372

相关文章