題目描述
Ginny 的生日馬上就來了。魔法大叔 Herry 準備給他的新妹子一個生日禮物。禮物是由
Herry想知道,究竟能有多少不同的手鐲,將這個結果
輸入格式
輸入包含多組數據。第一行一個正整數
接下來的數據分爲
接下來
Burnside引理裸題,另外要求滿足一定限定條件的
#include<bits/stdc++.h>
typedef long long ll;
const int P = 9973;
int Case, n, m, k, u, v, d[(int)1e5];
struct matrix{
int a[11][11];
};
matrix e, full;
matrix operator * (const matrix &a, const matrix &b) {
matrix c;
memset(&c, 0, sizeof(c));
for (int i=1; i <= m; i++)
for (int j=1; j <= m; j++) {
for (int k=1; k <= m; k++)
c.a[i][j] += a.a[i][k] * b.a[k][j];
c.a[i][j] %= P;
}
return c;
}
matrix pow(matrix x, int k) {
matrix ret = e;
for (; k; k >>= 1, x = x * x)
if (k & 1) ret = ret * x;
return ret;
}
int phi(int x) {
int ret = x;
for (int i=2; i * i <= x; i++)
if (x % i == 0) {
ret = ret / i * (i - 1);
while (x % i == 0) x /= i;
}
if (x > 1) ret = ret / x * (x - 1);
return ret;
}
ll pow(ll x, int k) {
ll ret = 1;
for (; k; k >>= 1, x = x * x % P)
if (k & 1) ret = ret * x % P;
return ret;
}
ll inv (ll x) {return pow(x, P - 2);}
int main() {
scanf("%d", &Case);
for (int i=1; i <= 10; i++)
e.a[i][i] = 1;
for (int i=1; i <= 10; i++)
for (int j=1; j <= 10; j++)
full.a[i][j] = 1;
while (Case--) {
scanf("%d%d%d", &n, &m, &k);
matrix tra = full;
while (k--)
scanf("%d%d", &u, &v),
tra.a[u][v] = 0,
tra.a[v][u] = 0;
matrix cp = tra;
ll ans = 0;
int kind = 0;
for (int i=1; i * i <= n; i++)
if (n % i == 0)
d[++kind] = i,
d[++kind] = n / i;
if (kind >= 2 && d[kind] == d[kind - 1]) kind--;
for (int k=1; k <= kind; k++)
if (n % d[k] == 0) {
matrix f = e * pow(tra, n / d[k] - 1);
ll tans = 0;
for (int i=1; i <= m; i++)
for (int j=1; j <= m; j++)
if (cp.a[i][j]) tans += f.a[i][j];
ans = (ans + tans * phi(d[k]));
}
printf("%lld\n", ans * inv(n) % P);
}
return 0;
}