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;
    }
    
  • 相关阅读:
    Balance的数学思想构造辅助函数
    1663. Smallest String With A Given Numeric Value (M)
    1680. Concatenation of Consecutive Binary Numbers (M)
    1631. Path With Minimum Effort (M)
    1437. Check If All 1's Are at Least Length K Places Away (E)
    1329. Sort the Matrix Diagonally (M)
    1657. Determine if Two Strings Are Close (M)
    1673. Find the Most Competitive Subsequence (M)
    1641. Count Sorted Vowel Strings (M)
    1679. Max Number of K-Sum Pairs (M)
  • 原文地址:https://www.cnblogs.com/NLDQY/p/12238445.html
Copyright © 2011-2022 走看看