我是靠谱客的博主 犹豫飞机,最近开发中收集的这篇文章主要介绍LOJ#6436. 「PKUSC2018」神仙的游戏,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

传送门

题解:
瞎JB猜了个结论居然是对的,看了题解知道为什么对了。

我们考虑先做模糊串匹配,那么长度不大于 n2 n 2 的串只需要匹配上就行了。

否则我们判断他的每一个周期子串是否能作前缀即可。 原因是如果有非法的必然是: 0??1 0 → ? → ? → 1 类似的情况,而他的周期子串也会有这种情况直到直接出现 01 0 → 1 ,我们跳每一个周期子串判一下就好了。

根据调和级数,时间复杂度 O(nlogn) O ( n log ⁡ n )

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;

const int mod=998244353, G=3;
inline int add(int x,int y) {return (x+y>=mod) ? (x+y-mod) : (x+y);}
inline int dec(int x,int y) {return (x-y<0) ? (x-y+mod) : (x-y);}
inline int mul(int x,int y) {return (LL)x*y%mod;}
inline int power(int a,int b,int rs=1) {for(;b;b>>=1,a=mul(a,a)) if(b&1) rs=mul(rs,a); return rs;}
inline int cinv(int a) {return power(a,mod-2);}

const int N=5e5+50;
char s[N];
int n,ok[N],A[N*8],B[N*8],w[N*8],pos[N*8],k; 
inline void init(int nn) {
    for(k=1;k<=nn;k<<=1);
    for(int i=1;i<k;i++) pos[i]=(i&1) ? ((pos[i>>1]>>1)^(k>>1)) : (pos[i>>1]>>1);
}
inline void dft(int *a,int o=1) {
    for(int i=1;i<k;i++) if(pos[i]>i) swap(a[pos[i]],a[i]);
    for(int bl=1;bl<k;bl<<=1) {
        int tl=bl<<1, wn=power(G,(mod-1)/tl);
        w[0]=1; for(int i=1;i<bl;i++) w[i]=mul(w[i-1],wn);
        for(int bg=0;bg<k;bg+=tl)
            for(int j=0;j<bl;j++) {
                int &t1=a[bg+j],&t2=a[bg+j+bl],t=mul(t2,w[j]);
                t2=dec(t1,t); t1=add(t1,t);
            }
    }
    if(!~o) {
        const int inv=power(k,mod-2);
        for(int i=0;i<k;i++) a[i]=mul(a[i],inv);
    }
}
inline void mul(int *a,int *b,int *c) {
    dft(a); dft(b); 
    for(int i=0;i<k;i++) c[i]=mul(a[i],b[i]);
    dft(c,-1); reverse(c+1,c+k);
}
int main() {
    scanf("%s",s); n=strlen(s);
    for(int i=0;i<n;i++) A[i]=(s[i]=='0'), B[n-i-1]=(s[i]=='1');
    init(2*n); mul(A,B,A);
    for(int i=1;i<=n/2;i++) 
        ok[i]=(!A[i-1] && !A[2*n-i-1]);
    for(int i=n/2+1;i<n;i++) {
        ok[i]=(!A[i-1] && !A[2*n-i-1]);
        int len=n-i, t=i-len;
        while(t>0 && ok[i]) ok[i]&=ok[t], t-=len;
    }
    LL ans=0;
    for(int i=1;i<n;i++) if(ok[i]) ans^=((LL)i*i);
    ans^=(LL)n*n; cout<<ans<<'n';
}

最后

以上就是犹豫飞机为你收集整理的LOJ#6436. 「PKUSC2018」神仙的游戏的全部内容,希望文章能够帮你解决LOJ#6436. 「PKUSC2018」神仙的游戏所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(45)

评论列表共有 0 条评论

立即
投稿
返回
顶部