"PKUSC2018" god games (border nature + NTT)

https://loj.ac/problem/6436

Remember when hzj less likely to talk about this topic more than a year ago, is now able to easily cut off.

Consider the nature of the border, if a length \ (I \) of the border, the \ (\ FORALL X \ in [. 1, I], S [X] = S [X + (Ni)] \) .

6,187,655 \ (g [i] = f [ni] \)

Then, if \ (s [i] = 0 , s [j] = 1 or S [I] =. 1, S [J] = 0 (I <J) \) , then \ (\ forall d | ji, g [d] = 0 \)

First with NTT determine what \ (JI \) satisfies \ (s [i] = 0 , s [j] = 1 or s [i] = 1, s [j] = 0 (i <j) \)

Then \ (O (n ~ log ~ n) \) enumerator to obtain a multiple number of each \ (G [D] \) , gone

Code:


#include<bits/stdc++.h>
#define fo(i, x, y) for(int i = x, _b = y; i <= _b; i ++)
#define ff(i, x, y) for(int i = x, _b = y; i <  _b; i ++)
#define fd(i, x, y) for(int i = x, _b = y; i >= _b; i --)
#define ll long long
#define pp printf
#define hh pp("\n")
using namespace std;

const int mo = 998244353;

ll ksm(ll x, ll y) {
	ll s = 1;
	for(; y; y /= 2, x = x * x % mo)
		if(y & 1) s = s * x % mo;
	return s;
}

#define V vector<ll>
#define si size()
#define re resize

const int nm = 1048576;
namespace ntt {
	int r[nm]; ll w[nm];
	void build() {
		for(int i = 1; i < nm; i *= 2) {
			w[i] = 1; ll v = ksm(3, (mo - 1) / 2 / i);
			ff(j, 1, i) w[i + j] = w[i + j - 1] * v % mo;
		}
	}
	void dft(ll *a, int n, int f) {
		ff(i, 0, n) {
			r[i] = r[i / 2] / 2 + (i & 1) * (n / 2);
			if(i < r[i]) swap(a[i], a[r[i]]);
		} ll b;
		for(int i = 1; i < n; i *= 2) for(int j = 0; j < n; j += 2 * i) ff(k, 0, i)
			b = a[i + j + k] * w[i + k], a[i + j + k] = (a[j + k] - b) % mo, a[j + k] = (a[j + k] + b) % mo;
		if(f == -1) {
			reverse(a + 1, a + n);
			b = ksm(n, mo - 2);
			ff(i, 0, n) a[i] = (a[i] + mo) * b % mo;
		}
	}
}
using ntt :: dft;

const int N = 5e5 + 5;

char s[N]; int n, n0;

int f[N];

ll a0[nm], a1[nm];
ll b0[nm], b1[nm];
ll d[nm];

int main() {
	ntt :: build();
	scanf("%s", s + 1);
	n = strlen(s + 1);
	n0 = 1; while(n0 <= 2 * n) n0 *= 2;
	fo(i, 1, n) if(s[i] == '0')
		a0[n - i] = a1[i] = 1;
	fo(i, 1, n) if(s[i] == '1')
		b0[n - i] = b1[i] = 1;
	dft(a0, n0, 1); dft(a1, n0, 1);
	dft(b0, n0, 1); dft(b1, n0, 1);
	ff(i, 0, n0) {
		d[i] = (a0[i] * b1[i] + a1[i] * b0[i]) % mo;
	}
	dft(d, n0, -1);
	fo(i, 1, n) f[i] = d[n + i];
	fo(i, 1, n) fo(j, 1, n / i) f[i] |= f[i * j];
	ll ans = 0;
	fo(i, 1, n) if(!f[n - i]) ans ^= (ll) i * i;
	pp("%lld\n", ans);
}

Guess you like

Origin www.cnblogs.com/coldchair/p/12622937.html