题意:对一张像素图可以执行旋转、翻转、div、mix等操作,现在给出一个操作序列,问重复进行多少次这个操作序列,可以使得任意n*n的像素图变回原样。
转换一下就是:设操作序列为置换A,则求m使得A^m为全等置换(所有元素都映射到自己)
对于每个长度为L的循环B,当m为B的整数倍时,B^m为全等置换,所以只需要把操作序列对应的置换拆解成多个循环,求每个循环长度的LCM即可,然后题目就变成了模拟。
(我的mix_竟然能写超时。。。就是代码中的imix1,换了个写法就过了)
#include <bits/stdc++.h>
#include<cstdio>
#include<cstring>
using namespace std;
#define fi first
#define se second
#define pii pair<int,int>
#define pll pair<long long ,long long>
#define mp make_pair
typedef long long ll;
const int maxn=10005;
const int maxm=1e5+15;
const int maxe=200005;
const int mod=1e9+7;
const int inf=0x3f3f3f3f;
int n,m;
int id[1050][1050];
int cnt[1050][1050];
bool vis[1050][1050];
inline int idx(int x,int y){
return x*n+y;
}
char str[1050];
ll k,ggg;
void cop(){
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
id[i][j]=cnt[i][j];
}
}
}
void imix(){
for(int i=0;i<n;i+=2){
for(int j=0;j<n/2;j++){
cnt[i][j]=id[i][j*2];
cnt[i+1][j]=id[i][j*2+1];
cnt[i][n/2+j]=id[i+1][j*2];
cnt[i+1][n/2+j]=id[i+1][j*2+1];
}
}
cop();
}
void imix1(){
for(int i=0;i<n;i++){
int k2=i/2*2;
for(int j=0;j<n;j++){
if(i&1){
for(int j=0;j<n;j++){
int cc=n/2+j/2;
if(j&1){
cnt[k2+1][cc]=id[i][j];
}
else cnt[k2][cc]=id[i][j];
}
}
else{
int cc=j/2;
if(j&1){
cnt[k2+1][cc]=id[i][j];
}
else{
cnt[k2][cc]=id[i][j];
}
}
}
}
cop();
}
void mix(){
for(int i=0;i<n;i++){
int k2=i/2*2;
if(i&1){
for(int j=0;j<n;j++){
int cc=n/2+j/2;
if(j&1){
cnt[i][j]=id[k2+1][cc];
}
else cnt[i][j]=id[k2][cc];
}
}
else{
for(int j=0;j<n;j++){
int cc=j/2;
if(j&1){
cnt[i][j]=id[k2+1][cc];
}
else{
cnt[i][j]=id[k2][cc];
}
}
}
}
cop();
}
void idiv(){
int cc=-1;
for(int i=0;i<n;i+=2){
cc++;
for(int j=0;j<n;j++){
cnt[i][j]=id[cc][j];
}
}
cc=n/2-1;
for(int i=1;i<n;i+=2){
cc++;
for(int j=0;j<n;j++){
cnt[i][j]=id[cc][j];
}
}
cop();
}
void div(){
for(int i=0;i<n/2;i++){
for(int j=0;j<n;j++){
cnt[i][j]=id[i*2][j];
}
}
int cc=-1;
for(int i=n/2;i<n;i++){
cc+=2;
for(int j=0;j<n;j++){
cnt[i][j]=id[cc][j];
}
}
cop();
}
void bvsm(){
for(int i=0;i<n/4;i++){
for(int j=0;j<n;j++){
swap(id[n/2+i][j],id[n-1-i][j]);
}
}
}
void bhsym(){
for(int i=n/2;i<n;i++){
for(int j=0;j<n/2;j++){
swap(id[i][j],id[i][n-1-j]);
}
}
}
void sym(){
for(int i=0;i<n;i++)
for(int j=0;j<n/2;j++){
swap(id[i][j],id[i][n-1-j]);
}
}
void rot(){
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
cnt[i][j]=id[j][n-1-i];
}
}
cop();
}
void irot(){
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
cnt[i][j]=id[n-1-j][i];
}
}
cop();
}
void calc(int lef,int rig){
if(lef>=rig)return;
if(str[lef]=='i')return;
else if(str[lef]=='r'){
if(str[rig]=='-')irot();
else rot();
}
else if(str[lef]=='s')sym();
else if(str[lef]=='b'){
if(str[lef+1]=='h'){
bhsym();
}
else{
bvsm();
}
}
else if(str[lef]=='d'){
if(str[rig]=='-')idiv();
else div();
}
else{
if(str[rig]=='-')imix();
else mix();
}
}
void print(){
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
printf("%d\t",id[i][j]);
}
printf("\n");
}
puts("");
}
ll gcd(ll a,ll b){
if(b==0)return a;
return gcd(b,a%b);
}
int main(){
int T;
scanf("%d",&T);
while(T--){
memset(vis,0,sizeof(vis));
scanf("%d",&n);
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
id[i][j]=idx(i,j);
}
}
getchar();
gets(str);
m=strlen(str);
int last=m-1,cc=m-1;
//print();
for(int cc=m-1;cc>=0;cc--){
if(str[cc]==' '||cc==0){
if(cc==0)calc(cc,last);
else calc(cc+1,last);
// print();
last=cc-1;
}
}
ggg=0;
k=1;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(vis[i][j])continue;
int cntx=i,cnty=j;
int cc=0;
while(vis[cntx][cnty]==0){
vis[cntx][cnty]=1;
int val=id[cntx][cnty];
cntx=val/n;
cnty=val%n;
cc++;
}
k*=(cc/gcd(k,cc));
}
}
printf("%lld\n",k);
if(T)printf("\n");
}
return 0;
}
/*
1
1024
mix- mix- mix- mix- mix- mix- mix- mix- mix- mix- mix- mix-
mix mix mix mix mix mix mix mix mix mix mix mix mix mix mix mix mix mix mix mix mix mix mix mix
id id- rot rot- sym sym- bhsym bhsym- bvsm bvsm- div div- div div-
id id- rot rot- sym sym- bhsym bhsym- bvsm bvsm- div div- mix mix-
*/