• 「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);
    }
    
  • 相关阅读:
    页面上一些小icon的制作方法及技术选择
    移动端h5页面touch事件与点击穿透问题
    浅析 jquerydom操作方法--remove(),detach(),empty()
    jquery中attr和prop的区别
    正则表达式的基本入门
    浏览器对中文标点符号折行的处理差异
    关于阴影:box-shadow
    ubuntu nginx ftp 配置图片服务器
    ubuntu 18 安装ftp 并远程配置访问用户
    WIn10系统软件默认安装c盘后消失看不见问题
  • 原文地址:https://www.cnblogs.com/coldchair/p/12622937.html
Copyright © 2020-2023  润新知