zoukankan      html  css  js  c++  java
  • 「PKUSC2018」神仙的游戏(border性质+NTT)

    https://loj.ac/problem/6436

    记得一年多前hzj讲这题时不太会的,现在已经能很容易切掉了。

    考虑border的性质,若有一个长度为(i)的border,则(forall xin[1,i],s[x]=s[x+(n-i)])

    (g[i]=f[n-i])

    那么,若有(s[i]=0,s[j]=1或s[i]=1,s[j]=0(i<j)),则(forall d|j-i,g[d]=0)

    先用NTT求出有哪些(j-i)满足(s[i]=0,s[j]=1或s[i]=1,s[j]=0(i<j))

    (O(n~log~n))枚举每个数的倍数得到(g[d]),就没了

    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("
    ")
    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
    ", ans);
    }
    
  • 相关阅读:
    为什么Java中 wait 方法需要在 synchronized 的方法中调用?
    XML常用解析API有哪几种?
    Dubbo 和 Spring Cloud 的区别?
    Java 线程池中 submit() 和 execute()方法有什么区别?
    详细描述一下 Elasticsearch 搜索的过程?
    为表中得字段选择合适得数据类型 ?
    Json有什么作用?
    Ajax的乱码解决问题?
    eclipse安装配置记录
    srs部署/webrtc拉流
  • 原文地址:https://www.cnblogs.com/coldchair/p/12622937.html
Copyright © 2011-2022 走看看