zoukankan      html  css  js  c++  java
  • [PKUSC2018]神仙的游戏(FFT)

    给定一个01?串,对所有len询问是否存在一种填法使存在长度为len的border。

    首先有个套路的性质:对于一个长度为len的border,这个字符串一定有长度为n-len的循环节(最后可以不完整)。

    逆推得到,如果有一个0位置和一个1位置之差为len,则所有len的因数k的n-k都不可能成为border。

    先将b翻转,作差卷起来,然后$O(nlog n)$枚举倍数即可。

    $A(x)=x^{n-1}A(frac 1x)$是作差卷积的本质。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #define rep(i,l,r) for (int i=(l); i<=(r); i++)
     5 using namespace std;
     6 
     7 const int N=3000010,mod=998244353,G=3;
     8 int n,len,l,a[N],b[N],rev[N],lg[N];
     9 char s[N];
    10 
    11 int ksm(int a,int b){
    12     int res=1;
    13     for (; b; a=1ll*a*a%mod,b>>=1)
    14         if (b & 1) res=1ll*res*a%mod;
    15     return res;
    16 }
    17 
    18 void NTT(int a[],int n,int f){
    19     for (int i=0; i<n; i++) if (i<rev[i]) swap(a[i],a[rev[i]]);
    20     for (int i=1; i<n; i<<=1){
    21         int wn=ksm(G,(f==1) ? (mod-1)/(i<<1) : (mod-1)-(mod-1)/(i<<1));
    22         for (int p=i<<1,j=0; j<n; j+=p)
    23             for (int w=1,k=0; k<i; k++,w=1ll*w*wn%mod){
    24                 int x=a[j+k],y=1ll*w*a[i+j+k]%mod;
    25                 a[j+k]=(x+y)%mod; a[i+j+k]=(x-y+mod)%mod;
    26             }
    27     }
    28     if (f==1) return;
    29     int inv=ksm(n,mod-2);
    30     for (int i=0; i<n; i++) a[i]=1ll*a[i]*inv%mod;
    31 }
    32 
    33 int main(){
    34     freopen("pkub.in","r",stdin);
    35     freopen("pkub.out","w",stdout);
    36     scanf("%s",s); n=strlen(s);
    37     for (len=1; len<=(n<<1); len<<=1) l++;
    38     for (int i=0; i<len; i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<(l-1));
    39     for (int i=0; i<n; i++) a[i]=s[i]=='0',b[i]=s[n-i-1]=='1';
    40     NTT(a,len,1); NTT(b,len,1);
    41     for (int i=0; i<len; i++) a[i]=1ll*a[i]*b[i]%mod;
    42     NTT(a,len,-1);
    43     long long ans=1ll*n*n;
    44     for (int i=1; i<n; i++){
    45         int f=1;
    46         for (int j=i; j<n; j+=i) if (a[n-j-1]|a[n+j-1]) { f=0; break; }
    47         if (f) ans^=1ll*(n-i)*(n-i);
    48     }
    49     printf("%lld
    ",ans);
    50     return 0;
    51 }
  • 相关阅读:
    redhat 6.4下PXE+Kickstart无人值守安装操作系统
    ubuntu14.04安装好Hadoo之后接着安装hbase和介绍常用命令
    避坑之Hadoop安装伪分布式(Hadoop3.2.0/Ubuntu14.04 64位)
    kindeditor文件上传设置文件说明为上传文件名(JSP版)
    sqlmap 扫描注入漏洞
    局域网内访问不同网段的主机(转记)
    cmd创建用户开启3389命令
    用python来更改windows开机密码
    代码安全之上传文件
    web渗透(转)
  • 原文地址:https://www.cnblogs.com/HocRiser/p/9163705.html
Copyright © 2011-2022 走看看