zoukankan      html  css  js  c++  java
  • 「PKUSC2018」神仙的游戏

    题目链接:Click here

    Solution:

    这道题感觉还是不太难的。。。

    考虑若存在一个长度为(len)(border),那么对于(forall iin [1,len])都有(s[i]=s[n-len+i])

    注意到下标之间的差值为(n-len),也就是说,所有下标差为(n-len)的位置必须相同

    这里的相同包括某一个是(?)的情况,也就是说(?)其实是没有影响的

    有了上面的条件,我们可以发现若有一对((0,1))的位置相差(l),那么对于所有的(x|l),都不存在长度为(n-x)(border)

    我们已经知道本题的关键就是((0,1))对了,那么如何来找呢?

    考虑构造两个生成函数(A(x),B(x))

    [A(x)=sum_{i=0}^{n-1} x^i[s_i=0]\ B(x)=sum_{i=0}^{n-1} x^i[s_i=1]\ ]

    我们知道卷积的形式就是指数相加,和为定值,那么我们现在要的是差为定值,那么把其中一个生成函数(reverse)即可

    现在我们得到了新的(C(x)=A(x)B(x))(C(x))的第(i)系数即为下标差为(i-n)((0,1))对数

    最后我们再枚举下标差即可,时间复杂度(O(n log n))

    Code:

    #include<bits/stdc++.h>
    #define Pi acos(-1.0)
    #define int long long 
    using namespace std;
    const int N=2e6+10;
    const double eps=1e-3;
    char s[N];
    int n,ans,len=1,tim,rtt[N],f[N];
    struct cp{double x,y;}A[N*2],B[N];
    cp operator + (cp a,cp b){return (cp){a.x+b.x,a.y+b.y};}
    cp operator - (cp a,cp b){return (cp){a.x-b.x,a.y-b.y};}
    cp operator * (cp a,cp b){return (cp){a.x*b.x-a.y*b.y,a.y*b.x+a.x*b.y};}
    void FFT(cp *a,int flag){
        for(int i=0;i<len;i++)
            if(i<rtt[i]) swap(a[i],a[rtt[i]]);
        for(int l=2;l<=len;l<<=1){
            cp wn=(cp){cos(flag*2*Pi/l),sin(flag*2*Pi/l)};
            for(int st=0;st<len;st+=l){
                cp w=(cp){1,0};
                for(int u=st;u<st+(l>>1);u++,w=w*wn){
                    cp x=a[u],y=w*a[u+(l>>1)];
                    a[u]=x+y,a[u+(l>>1)]=x-y;
                }
            }
        }
    }
    signed main(){
        scanf("%s",s);n=strlen(s);
        while(len<=(2*n)) len<<=1,++tim;
        for(int i=0;i<len;i++)
            rtt[i]=(rtt[i>>1]>>1)|((i&1)<<(tim-1));
        for(int i=0;i<n;i++){
            A[i].x=(s[i]=='1');
            B[n-i-1].x=(s[i]=='0');
        }
        FFT(A,1);FFT(B,1);
        for(int i=0;i<=len;i++) A[i]=A[i]*B[i];
        FFT(A,-1);for(int i=0;i<=len;i++) A[i].x=(A[i].x)/len;
        for(int i=n-1;i;i--)
            if(A[n-1+i].x+A[n-1-i].x>eps) f[i]=1;
        for(int i=1;i<n;i++){
            int flag=1;
            for(int j=1;j*i<=n;j++)
                if(f[j*i]){flag=0;break;}
            if(flag) ans=ans^((n-i)*1ll*(n-i));
        }ans^=(n*1ll*n);
        printf("%lld
    ",ans);
        return 0;
    }
    
  • 相关阅读:
    CodeForces 734F Anton and School
    CodeForces 733F Drivers Dissatisfaction
    CodeForces 733C Epidemic in Monstropolis
    ZOJ 3498 Javabeans
    ZOJ 3497 Mistwald
    ZOJ 3495 Lego Bricks
    CodeForces 732F Tourist Reform
    CodeForces 732E Sockets
    CodeForces 731E Funny Game
    CodeForces 731D 80-th Level Archeology
  • 原文地址:https://www.cnblogs.com/NLDQY/p/12238445.html
Copyright © 2011-2022 走看看