sgu 208 分类: sgu templates 2015-06-17 01:40 24人阅读 评论(0) 收藏
感谢
设
令
如果用
令
时间复杂度为
在本题中,
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
const int maxn = 23, maxm = 25, maxl = 100;
const int Base = 1e4, Blen = 4;
struct BigNum
{
int num[maxl], l;
void plus(int &hp,int &tp)
{
hp += tp/Base, tp %= Base;
}
void digit()
{
for(int i = 1; i <= l; i++) plus(num[i+1] ,num[i]);
while(num[l+1]) ++l, plus(num[l+1], num[l]);
}
void operator +=(const BigNum &add)
{
l = std::max(l, add.l);
for(int i = 1; i <= l; i++)
num[i] += add.num[i];
digit();
}
void operator /=(const int x)
{
int nl = 0;
for(int i = l; i > 0; i--)
{
num[i-1] += num[i]%x*Base, num[i] /= x;
if(!nl && num[i]) nl = i;
}
l = nl;
}
void prt()
{
printf("%d",num[l]);
for(int i = l-1; i > 0; i--)
printf("%04d",num[i]);
}
};
int n, m;
bool square;int G;
int f[maxn*maxm];
BigNum pow2[maxn*maxm];
BigNum ans;
void PreWork()
{
if(square = (n == m))
G = (n*m)<<2;
else
G = (n*m)<<1;
pow2[0].l = pow2[0].num[1] = 1;
for(int i = 1; i <= n*m; i++)
pow2[i] = pow2[i-1], pow2[i] += pow2[i-1];
}
void Slide_Down()
{
static int tmp[maxn*maxm];
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
tmp[i%n*m+j] = f[(i-1)*m+j];
for(int i = 1; i <= n*m; i++) f[i] = tmp[i];
}
void Slide_Right()
{
static int tmp[maxn*maxm];
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
tmp[(i-1)*m+j%m+1] = f[(i-1)*m+j];
for(int i = 1; i <= n*m; i++) f[i] = tmp[i];
}
void Rotate()
{
static int tmp[maxn*maxm];
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
tmp[(j-1)*n+n-i+1] = f[(i-1)*m+j];
for(int i = 1; i <= n*m; i++) f[i] = tmp[i];
std::swap(n, m);
}
int calc()
{
static bool hash[maxn*maxm];
memset(hash,false,sizeof(hash));
int cnt = 0;
for(int i = 1; i <= n*m; i++)
for(int j = i; !hash[j]; j = f[j])
{
if(i == j) cnt++;
hash[j] = true;
}
return cnt;
}
void Polya()
{
for(int i = 1; i <= n*m; i++) f[i] = i;
for(int i = 1; i <= n; i++, Slide_Down())
for(int j = 1; j <= m; j++, Slide_Right())
{
ans += pow2[calc()];
Rotate();
if(square) ans += pow2[calc()];
Rotate();
ans += pow2[calc()];
Rotate();
if(square) ans += pow2[calc()];
Rotate();
}
ans /= G;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("sgu208.in","r",stdin);
freopen("sgu208.out","w",stdout);
#endif
std::cin >> n >> m;
PreWork(), Polya();
ans.prt();
#ifndef ONLINE_JUDGE
fclose(stdin);
fclose(stdout);
#endif
}
版权声明:本文为博主原创文章,未经博主允许不得转载。