A2 - Heidi Learns Hashing (Medium)

 n阶循环群,i阶生成群与gcd( n,i )阶生成群同构。

#include 
#include 
 
using namespace std;
 
#define DEBUG 0
#define ONLINE_JUDGE
 
#define MAXN 200010
 
template
T GCD(T a, T b) {
    T r;
    while(b)
        r = a % b, a = b, b = r;
    return a;
}
 
template
void AddMod(T& x, int p) {
	if (x >= p)
		x -= p;
}
char y[MAXN];
int n;
bool IsValid(int k) {
	static bool vis[MAXN];
	memset(vis, 0, (n+1) * sizeof(bool));
 
	for (int i = 0; i < n; ++i) {
		if (vis[i]) continue;
		int ans = y[i];
		vis[i] = true;
		int now = i + k;
		AddMod(now, n);
		while (now != i) {
			vis[now] = true;
			ans ^= y[now];
			AddMod(now += k, n);
		}
		if (ans) {
			return false;
		}
	}
	return true;
}
 
int main() {
#ifndef ONLINE_JUDGE
	freopen("in.in", "r", stdin);
	freopen("out.out", "w", stdout);
#endif
	int ans = 1;
	static bool res[MAXN];
 
	scanf("%d", &n);
	memset(res, 0, sizeof(res));
	getchar();
	for (int i = 0; i < n; ++i) {
		y[i] = getchar() - '0';
	}
	for (int i = 0; i < n; ++i) {
		if (y[i]) {
			--ans;
			break;
		}
	}
 
	for (int k = 1; k < n; ++k) {
		int gcd = GCD(k, n);
		if (k == gcd) {
			res[k] = IsValid(k);
		} else {
			res[k] = res[gcd];
		}
	}
	for (int i = 1; i < n; ++i) {
		if (res[i]) {
			++ans;
		}
	}
 
	printf("%d", ans);
 
	return 0;
}

 

你可能感兴趣的:(置换群)