异或专题2

>> 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;
}
 
 

若有不理解欢迎评论

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值