zoukankan      html  css  js  c++  java
  • 洛谷P4607 [SDOI2018] 反回文串

    设长度为 (n) 字符集大小为 (k) 的回文串的个数为 (g(n)=k^{leftlceilfrac{n}{2} ight ceil}),回文串的每个循环位移都有贡献,但因为循环同构,直接算会算重。不难发现若一个回文串是由同一个串重复循环得到的,那么该串也为回文串,即若有回文串 (s=t^k),则 (t) 也为回文串。考虑枚举回文串的最小循环串长度。

    (v(n)) 为一个回文串的最小循环串长度为 (n) 时的贡献,(n) 为偶数时会计算两遍,因为当回文串循环位移了 (frac{n}{2}) 后,又会得到一个最小循环串长度为 (n) 的回文串,因此得 (v(n)=nfrac{1+left[ 2 otmid n ight]}{2})

    (f(n)) 为最小循环串为其本身的长度为 (n) 的回文串个数,得:

    [largeegin{aligned} sum_{dmid n} f(d)&=g(n)\ f(n)&=sum_{dmid n}g(d)muleft(frac{n}{d} ight)\ end{aligned} ]

    得答案为:

    [largeegin{aligned} &sum_{dmid n} f(d)v(d)\ =&sum_{dmid n}sum_{tmid d}g(t)muleft(frac{d}{t} ight)v(d)\ =&sum_{tmid n}g(t)sum_{dmid frac{n}{t}}muleft(d ight)v(dt)\ end{aligned} ]

    考虑进一步化简 (sumlimits_{dmid frac{n}{t}}muleft(d ight)v(dt)),发现除了 (d) 为偶数且 (t) 为奇数的情况,都有 (v(dt)= dv(t))。考虑 (d) 为偶数且 (t) 为奇数时一定有 (frac{n}{t}) 也为偶数,于是可以将满足 (mu(d) eq 0)(d) 中质因子没有 (2)(d)(2d) 进行配对,因为此时有 (v(dt)=dt=v(2dt)),所以两两配对后得 (sumlimits_{dmid frac{n}{t}}muleft(d ight)v(dt)=0)

    于是就可以代入 (v(dt)= dv(t)),得答案为:

    [largeegin{aligned} &sum_{tmid n}g(t)v(t)sum_{dmid frac{n}{t}}muleft(d ight)d\ =&sum_{tmid n}g(t)v(t)prod_{pmid frac{n}{t}}left( 1-p ight) end{aligned} ]

    (Pollard-Rho)(n) 质因数分解后,用 (dfs) 枚举 (n) 的约数,(dfs) 过程中维护 (prodlimits_{pmid frac{n}{t}}left( 1-p ight)) 即可。

    #include<bits/stdc++.h>
    #define maxn 110
    using namespace std;
    typedef long long ll;
    template<typename T> inline void read(T &x)
    {
        x=0;char c=getchar();bool flag=false;
        while(!isdigit(c)){if(c=='-')flag=true;c=getchar();}
        while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
        if(flag)x=-x;
    }
    ll T,n,k,p,cnt,tot,ans;
    ll pri[12]={2,3,5,7,11,13,17,19},t[maxn],v[maxn],a[maxn];
    ll mul(ll x,ll y,ll mod)
    {
    	ll c=(long double)x*y/mod+0.5;
    	c=x*y-c*mod;
    	return c<0?c+mod:c;
    }
    ll qp(ll x,ll y,ll mod)
    {
        ll v=1;
        while(y)
        {
            if(y&1) v=mul(v,x,mod);
            x=mul(x,x,mod),y>>=1;
        }
        return v%mod;
    }
    bool check(ll x,ll p,ll mod)
    {
        ll t=qp(x,p,mod);
        if(t==mod-1) return true;
        if(t==1) return p&1?true:check(x,p/2,mod);
        return false;
    }
    bool Miller_Rabin(ll n)
    {
        if(n==1) return false;
        if(n<=3) return true;
        if(!(n&1)) false;
        for(int i=0;i<8;++i)
        {
            if(n==pri[i]) return true;
            if(!check(pri[i],n-1,n)) return false;
        }
        return true;
    }
    ll gcd(ll a,ll b)
    {
        return b?gcd(b,a%b):a;
    }
    ll f(ll x,ll y,ll mod)
    {
        return (mul(x,x,mod)+y)%mod;
    }
    ll Pollard_Rho(ll x)
    {
        ll s=0,t=0,c=(ll)rand()%(x-1)+1,val=1;
        for(ll goal=1;;goal<<=1,s=t,val=1)
        {
            for(ll step=1;step<=goal;++step)
            {
                t=f(t,c,x);
                val=mul(val,abs(t-s),x);
                if(step%127==0)
                {
                    ll d=gcd(val,x);
                    if(d>1) return d;
                }
            }
            ll d=gcd(val,x);
            if(d>1) return d;
        }
    }
    void fac(ll x)
    {
        if(x<2) return;
        if(Miller_Rabin(x)) 
        {
            t[++cnt]=x;
            return;
        }
        ll p=x;
        while(p>=x) p=Pollard_Rho(x);
        fac(x/p),fac(p);
    }
    void dfs(int x,ll d,ll t)
    {
        if(x==tot+1)
        {
            if(!(n/d&1)||(d&1))
                ans=(ans+qp(k,(n/d+1)/2,p)*(((n/d&1)?n/d:n/d/2)%p)%p*t%p)%p;
            return;
        }
        dfs(x+1,d,t),t=t*(1-v[x]%p+p)%p;
        for(int i=1;i<=a[x];++i) d*=v[x],dfs(x+1,d,t);
    }
    int main()
    {
        srand((ll)new char),read(T);
        while(T--)
        {
            read(n),read(k),read(p),k%=p,cnt=tot=ans=0;
            fac(n),sort(t+1,t+cnt+1);
            for(int i=1;i<=cnt;++i)
            {
                if(t[i]!=t[i-1]) v[++tot]=t[i],a[tot]=0;
                a[tot]++;
            }
            dfs(1,1,1),printf("%lld
    ",ans);
        }
        return 0;
    }
    
  • 相关阅读:
    2013上半年学习目录
    《linux c编程指南》学习手记4
    Oracle二三事之 Oracle SPARC SuperCluster的九大技术优势
    《linux c编程指南》学习手记5
    Oracle二三事之 数据迁移注意事项
    《linux c编程指南》学习手记3
    在IIS中实现JSP
    为什么匿名内部类参数必须为final类型
    sql server和mysql变量赋值的区别 以及 MySql Declare
    android上传文件到服务器
  • 原文地址:https://www.cnblogs.com/lhm-/p/14334376.html
Copyright © 2011-2022 走看看