>> face <<
题意:给定一个01序列Y,要求序列X的个数, 且 X满足 :
Y = X ⨂ ( X s h i f t ( i ) ) ( i ∈ [ 1 , X . s i z e ( ) ] ) Y = X \bigotimes (X ^{shift(i)}) (i \in [1, X.size()]) Y=X⨂(Xshift(i))(i∈[1,X.size()])
其中 shift(i) 表示 x 序列 右移i位, 左端的空白用右端多出来的部分填 , 例如
0011 ⇒ s h i f t ( 1 ) 1001 ⇒ s h i f t ( 2 ) 0110 0011 \xRightarrow{shift(1) } 1001 \xRightarrow{shift(2) } 0110 0011shift(1)1001shift(2)0110
Strategy: 先假设 n = 12, i = 3;
pho:
which means:
当我们确定某个i的时候,我们可以写出gcd(y.size, i)个方程(所有方程都是mod 2意义下的)最后判断方程是否满足就可以了
#include<bits/stdc++.h>
#include<bits/extc++.h>
#define oo INT_MAX
#define ll long long
#define db double
#define mp(a, b) make_pair(a, b)
#define all(a) a.begin(), a.end()
#define met(a, b) memset(a, b, sizeof(a))
#define _rep(i, a, b) for(int i = (a); i <= (b); ++i)
#define _rev(i, a, b) for(int i = (a); i >= (b); --i)
#define _for(i, a, b) for(int i = (a); i < (b) ;++i)
#define lowbit(x) x & (-x)
using namespace std;
using namespace __gnu_pbds;
const int maxn = 2e5 + 1;
// FILE *o = freopen("C:\\Users\\Jason.Z\\Desktop\\in.txt", "r", stdin);
// assert(o != NULL);
// FILE *e = freopen("C:\\Users\\Jason.Z\\Desktop\\out.txt", "w", stdout);
// assert(e != NULL);
int n;
vector<int> num(maxn), G(maxn);
int main() {
ios::sync_with_stdio(0);
cin >> n;
string s;
cin >> s;
_for(i, 0, n){
num[i] = s[i] - '0';
G[__gcd(n, i)]++;
}
if(n == 1 && num[0] == 0){
return puts("1"), 0;
}
ll ans = 0;
_rep(i, 1, n){
if(G[i] == 0)continue;
bool is_right = 1;
_for(j, 0, i){
int sum = 0;
for(int q = j;q < n; q += i)sum += num[q];
if(sum & 1 != 0){is_right = 0; break;}
}
if(is_right)ans += G[i];
}
cout << ans << endl;
}