一道置换题,置换类型的题目都可以转化成若干个有向圈的模型进行思考,此题先把题目给出操作组合得到的置换求出来,分解成循环,而循环之间相互是不会影响的,单独的把每个循环看成一个有向圈,每次操作都会是所有的边指向下一个节点,所以经过k(k为循环中元素个数的倍数)次操作可以是每条边指向自己,所以答案就是每个循环元素个数的最小公倍数
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <queue>
#include <algorithm>
#include <vector>
#include <cstring>
#include <stack>
#include <cctype>
#include <utility>
#include <map>
#include <string>
#include <climits>
#include <set>
#include <string>
#include <sstream>
#include <utility>
#include <ctime>
using std::priority_queue;
using std::vector;
using std::swap;
using std::stack;
using std::sort;
using std::max;
using std::min;
using std::pair;
using std::map;
using std::string;
using std::cin;
using std::cout;
using std::set;
using std::queue;
using std::string;
using std::istringstream;
using std::make_pair;
using std::getline;
using std::greater;
using std::endl;
typedef long long LL;
const int MAXN((1 << 10)+5);
int N;
void subs_1(int (*ma1)[MAXN], int (*ma2)[MAXN], bool flag)
{
memcpy(ma1, ma2, sizeof(ma2[0])*N);
}
void subs_2(int (*ma1)[MAXN], int (*ma2)[MAXN], bool flag)
{
for(int i = 0; i < N; ++i)
for(int j = 0; j < N; ++j)
if(flag)
ma1[N-j-1][i] = ma2[i][j];
else
ma1[i][j] = ma2[N-j-1][i];
}
void subs_3(int (*ma1)[MAXN], int (*ma2)[MAXN], bool flag)
{
for(int i = 0; i < N; ++i)
for(int j = 0; j < N; ++j)
ma1[i][N-j-1] = ma2[i][j];
}
void subs_4(int (*ma1)[MAXN], int (*ma2)[MAXN], bool flag)
{
memcpy(ma1, ma2, sizeof(ma2[0])*N);
for(int i = N/2; i < N; ++i)
for(int j = 0; j < N; ++j)
ma1[i][N-j-1] = ma2[i][j];
}
void subs_5(int (*ma1)[MAXN], int (*ma2)[MAXN], bool flag)
{
memcpy(ma1, ma2, sizeof(ma2[0])*N);
int temp = N/2;
for(int i = N/2; i < N; ++i)
for(int j = 0; j < N; ++j)
ma1[N-i-1+temp][j] = ma2[i][j];
}
void subs_6(int (*ma1)[MAXN], int (*ma2)[MAXN], bool flag)
{
int ti = 0;
for(int i = 0; i < N; i += 2, ++ti)
for(int j = 0; j < N; ++j)
if(flag)
ma1[ti][j] = ma2[i][j];
else
ma1[i][j] = ma2[ti][j];
ti = N/2;
for(int i = 1; i < N; i += 2, ++ti)
for(int j = 0; j < N; ++j)
if(flag)
ma1[ti][j] = ma2[i][j];
else
ma1[i][j] = ma2[ti][j];
}
void subs_7(int (*ma1)[MAXN], int (*ma2)[MAXN], bool flag)
{
int tj;
for(int i = 0; i < N; i += 2)
{
tj = 0;
for(int j = 0; j < N; tj += j&1, ++j)
if(flag)
ma1[i][j] = ma2[i^(j&1)][tj];
else
ma1[i^(j&1)][tj] = ma2[i][j];
}
for(int i = 1; i < N; i += 2)
{
tj = N/2;
for(int j = 0; j < N; tj += j&1, ++j)
if(flag)
ma1[i][j] = ma2[i^1^(j&1)][tj];
else
ma1[i^1^(j&1)][tj] = ma2[i][j];
}
}
void (*fp[7])(int (*ma1)[MAXN], int (*ma2)[MAXN], bool flag) =
{subs_1, subs_2, subs_3, subs_4, subs_5, subs_6, subs_7};
LL gcd(LL a, LL b)
{
LL temp;
while(b)
{
temp = a%b;
a = b;
b = temp;
}
return a;
}
LL lcm(LL a, LL b)
{
return a/gcd(a, b)*b;
}
bool vis[MAXN*MAXN];
LL solve(int *arr)
{
int tn = N*N;
memset(vis, 0, sizeof(vis[0])*tn);
LL ans = 1LL;
for(int i = 0; i < tn; ++i)
if(!vis[arr[i]])
{
int t1 = arr[i];
int t2 = arr[t1];
int count = 1;
vis[t1] = true;
while(t2 != t1)
{
vis[t2] = true;
t2 = arr[t2];
++count;
}
ans = lcm(count, ans);
}
return ans;
}
string str;
string op[35];
int op_c;
int ma[2][MAXN][MAXN];
int subm[MAXN*MAXN];
map<string, pair<int, bool> > mp;
int main()
{
mp.insert(make_pair(string("id"), make_pair(0, true)));
mp.insert(make_pair(string("id-"), make_pair(0, false)));
mp.insert(make_pair(string("rot"), make_pair(1, true)));
mp.insert(make_pair(string("rot-"), make_pair(1, false)));
mp.insert(make_pair(string("sym"), make_pair(2, true)));
mp.insert(make_pair(string("sym-"), make_pair(2, false)));
mp.insert(make_pair(string("bhsym"), make_pair(3, true)));
mp.insert(make_pair(string("bhsym-"), make_pair(3, false)));
mp.insert(make_pair(string("bvsym"), make_pair(4, true)));
mp.insert(make_pair(string("bvsym-"), make_pair(4, false)));
mp.insert(make_pair(string("div"), make_pair(5, true)));
mp.insert(make_pair(string("div-"), make_pair(5, false)));
mp.insert(make_pair(string("mix"), make_pair(6, true)));
mp.insert(make_pair(string("mix-"), make_pair(6, false)));
//int T;
//scanf("%d", &T);
// while(T--)
while(~scanf("%d", &N))
{
// scanf("%d", &N);
while(getchar() != '\n');
getline(cin, str);
istringstream in(str);
op_c = 0;
while(in >> op[op_c])
++op_c;
int cur = 1, last = 0;
int ti = 0;
for(int i = 0; i < N; ++i)
for(int j = 0; j < N; ++j)
ma[last][i][j] = ti++;
for(int i = op_c-1; i >= 0; --i)
{
pair<int, bool> temp;
temp = mp[op[i]];
fp[temp.first](ma[cur], ma[last], temp.second);
cur ^= 1;
last ^= 1;
}
ti = 0;
for(int i = 0; i < N; ++i)
for(int j = 0; j < N; ++j)
subm[ti++] = ma[last][i][j];
printf("%I64d\n", solve(subm));
}
return 0;
}