zoukankan      html  css  js  c++  java
  • 【LOJ】#6436. 「PKUSC2018」神仙的游戏

    题解

    感觉智商为0啊QAQ

    显然对于一个长度为(len)的border,每个点同余(n - len)的部分必然相等

    那么我们求一个(f[a])数组,如果存在(s[x] = 0)(s[y] = 1)(|x - y| = a)

    这个很好求,只要把0和1分别挑出来,NTT卷一下就好了

    一个(len)合法,即它的(n - len)的倍数(k)(f[k])都等于0

    代码

    #include <bits/stdc++.h>
    #define fi first
    #define se second
    #define pii pair<int,int>
    #define pdi pair<db,int>
    #define mp make_pair
    #define pb push_back
    #define enter putchar('
    ')
    #define space putchar(' ')
    #define eps 1e-8
    #define mo 974711
    #define MAXN 500005
    //#define ivorysi
    using namespace std;
    typedef long long int64;
    typedef double db;
    template<class T>
    void read(T &res) {
        res = 0;char c = getchar();T f = 1;
        while(c < '0' || c > '9') {
    	if(c == '-') f = -1;
    	c = getchar();
        }
        while(c >= '0' && c <= '9') {
    	res = res * 10 + c - '0';
    	c = getchar();
        }
        res *= f;
    }
    template<class T>
    void out(T x) {
        if(x < 0) {x = -x;putchar('-');}
        if(x >= 10) {
    	out(x / 10);
        }
        putchar('0' + x % 10);
    }
    const int MOD = 998244353,MAXL = (1 << 20);
    int W[MAXL + 5],f[MAXL + 5],g[MAXL + 5],N;
    char s[MAXN];
    int inc(int a,int b) {
        return a + b >= MOD ? a + b - MOD : a + b;
    }
    int mul(int a,int b) {
        return 1LL * a * b % MOD;
    }
    int fpow(int x,int c) {
        int res = 1,t = x;
        while(c) {
    	if(c & 1) res = mul(res,t);
    	t = mul(t,t);
    	c >>= 1;
        }
        return res;
    }
    void NTT(int *p,int len,int on) {
        for(int i = 1 , j = len >> 1 ; i < len - 1 ; ++i) {
    	if(i < j) swap(p[i],p[j]);
    	int k = (len >> 1);
    	while(j >= k) {
    	    j -= k;
    	    k >>= 1;
    	}
    	j += k;
        }
        for(int h = 2 ; h <= len ; h <<= 1) {
    	int wn = W[(MAXL + MAXL / h * on) % MAXL];
    	for(int k = 0 ; k < len ; k += h) {
    	    int w = 1;
    	    for(int j = k ; j < k + h / 2 ; ++j) {
    		int u = p[j],t = mul(p[j + h / 2],w);
    		p[j] = inc(u,t);
    		p[j + h / 2] = inc(u,MOD - t);
    		w = mul(w,wn);
    	    }
    	}
        }
        if(on == -1) {
    	int InvL = fpow(len,MOD - 2);
    	for(int i = 0 ; i < len ; ++i) p[i] = mul(p[i],InvL);
        }
    }
    void Init() {
        W[0] = 1;W[1] = fpow(3,(MOD - 1) / MAXL);
        for(int i = 2 ; i < MAXL ; ++i) {
    	W[i] = mul(W[i - 1],W[1]);
        }
        scanf("%s",s + 1);
    }
    void Solve() {
        int t = 1;
        N = strlen(s + 1);
        while(t <= 2 * N) t <<= 1;
        for(int i = 1 ; i <= N ; ++i) {
    	f[i] = (s[i] == '1');
    	g[i] = (s[N - i + 1] == '0');
        }
        NTT(f,t,1);NTT(g,t,1);
        for(int i = 0 ; i < t; ++i) f[i] = mul(f[i],g[i]);
        NTT(f,t,-1);
        int64 ans = 1LL * N * N;
        for(int i = 1 ; i < N ; ++i) {
    	int t = i;
    	bool flag = 0;
    	while(t < N) {
    	    if(f[N - t + 1] || f[N + t + 1]) {flag = 1;break;}
    	    t += i;
    	}
    	if(!flag) ans ^= 1LL * (N - i) * (N - i);
        }
        out(ans);enter;
    }
    int main() {
    #ifdef ivorysi
        freopen("f1.in","r",stdin);
    #endif
        Init();
        Solve();
    }
    
  • 相关阅读:
    react的50个面试题
    什么是宏队列跟微队列
    宏队列与微队列
    数组都有哪些方法
    vuex 跟 vue属性
    高阶组件
    如何创建视图簇(View cluster)-SE54/SM34
    ◆◆0如何从维护视图(Maintenace view)中取数据-[VIEW_GET_DATA]
    ◆◆0如何在SM30维护表时自动写入表字段的默认值-事件(EVENT)
    ◆◆0SAP Query 操作教程
  • 原文地址:https://www.cnblogs.com/ivorysi/p/10123051.html
Copyright © 2011-2022 走看看