zoukankan      html  css  js  c++  java
  • bzoj 4913

    好毒瘤的一道题啊...

    对每个$a_{i}in S$,设$F(x)$为用$j$个$a_{i}$构造出$ja_{i}$的生成函数,那么$F(x)=sum_{j=1}^{∞}x^{ja_{i}}$

    根据这篇博客里的内容,可以求得:$F(x)=frac{1}{1-x^{a_{i}}}$

    设$t_{i}=[iin S]$,则用$S$集合中任意个数表示出一个数的生成函数即为$G(x)=prod_{i=1}^{n}[frac{1}{1-x^{i}}]^{t_{i}}$

     接下来做一些推导:

    两边取负对数,得:

    $-lnG(x)=sum_{i=1}^{n}t_{i}ln(1-x^{i})$

    对$ln(1-x^{i})$求导得到:

    $frac{-ix^{i-1}}{1-x^{i}}$

    把下半部分恢复成等比数列求和的形式:

    $-ix^{i-1}sum_{j=0}^{∞}x^{ij}$

    把外面的系数移进去:

    $-sum_{j=0}^{∞}ix^{ij+(i-1)}$

    然后积分:

    $int -sum_{j=0}^{∞}ix^{ij+(i-1)}=-sum_{j=1}^{∞}frac{i}{ij+i}x^{ij+i}$

    约分一下,就得到了:

    $-sum_{j=0}^{∞}frac{1}{j+1}x^{ij+i}$

    令$j=j+1$,有:

    $-sum_{j=1}^{∞}frac{1}{j}x^{ij}$

    对一个函数先求导再积分得到的就是原函数,因此有:

    $ln(1-x^{i})=-sum_{j=1}^{∞}frac{1}{j}x^{ij}$

    再带入原来的表达式:

    $-lnG(x)=-sum_{i=1}^{n}t_{i}sum_{j=1}^{∞}frac{1}{j}x^{ij}$

    约去两边的负号,也即:

    $lnG(x)=sum_{i=1}^{n}t_{i}sum_{j=1}^{∞}frac{1}{j}x^{ij}$

    考虑令$T=ij$,则$j=frac{T}{i}$,也即:

    $lnG(x)=sum_{i=1}^{n}t_{i}sum_{i|T}^{∞}frac{i}{T}x^{T}$

     优先枚举$T$,得到:

    $lnG(x)=sum_{T=1}^{∞}sum_{i|T}t_{i}frac{i}{T}x^{T}$

    如果设$lnG(x)$的第$i$项为$g(i)x^{i}$,则$g(i)=sum_{d|i}t_{d}frac{i}{T}$

    可以用枚举倍数的思想求解,这样的复杂度是调和级数$O(nlnn)$(即每计算出一个$d_{i}$,就枚举$i$的所有倍数$T$减去$d_{i}frac{i}{T}$的贡献即可)

    (不要忘了$G(x)$已知,但是需要多项式黑科技,因为模数不好...)

    (多项式黑科技精度问题可能被卡,用另一个黑科技就好)

    代码:

    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    #define ll long long
    #define ld long double
    #define maxn 100000
    using namespace std;
    const ld pi=acos(-1.0);
    const ll siz=32767;
    int n;
    ll mode;
    ll Ff[(1<<20)+5],Gg[(1<<20)+5];
    ll ff[(1<<20)+5];
    ll tempG[(1<<20)+5];
    ll ans[(1<<20)+5];
    ll gg[(1<<20)+5];
    ll inv[(1<<20)+5];
    int l[(1<<20)+5];
    int Lim=1;
    void init()
    {
        inv[0]=inv[1]=1;
        for(int i=2;i<=(1<<20);i++)inv[i]=(mode-mode/i)*inv[mode%i]%mode;
    }
    ll pow_mul(ll x,ll y)
    {
        ll ret=1;
        while(y)
        {
            if(y&1)ret=ret*x%mode;
            x=x*x%mode,y>>=1;
        }
        return ret;
    }
    
    struct cp
    {
        ld x,y;
        cp (){}
        cp (ld a,ld b):x(a),y(b){}
        cp operator + (const cp&a)const
        {
            return cp(a.x+x,a.y+y);
        }
        cp operator - (const cp&a)const
        {
            return cp(x-a.x,y-a.y);
        }
        cp operator * (const cp&a)const
        {
            return cp(a.x*x-a.y*y,a.x*y+a.y*x);
        }
    };
    cp get_w(cp a)
    {
        return cp(a.x,-a.y);
    }
    int to[(1<<20)+5];
    void FFT(cp *a,int len,int k)
    {
        for(register int i=0;i<len;i++)if(i<to[i])swap(a[i],a[to[i]]);
        for(register int i=1;i<len;i<<=1)
        {
            cp w0=cp(cos(pi/i),k*sin(pi/i));
            for(register int j=0;j<len;j+=(i<<1))
            {
                cp w=cp(1,0);
                for(int o=0;o<i;o++,w=w*w0)
                {
                    cp w1=a[j+o],w2=a[j+o+i]*w;
                    a[j+o]=w1+w2,a[j+o+i]=w1-w2;
                }
            }
        }
    }
    cp A[(1<<20)+5],B[(1<<20)+5],C[(1<<20)+5],D[(1<<20)+5];
    ll ret[(1<<20)+5];
    inline void MTT(ll *f,ll *g,ll *re,int len)
    {
        for(int i=0;i<len;i++)to[i]=((to[i>>1]>>1)|((i&1)<<(l[len]-1)));
        for(int i=0;i<len;i++)A[i]=B[i]=cp(0,0);
        for(int i=0;i<(len>>1);i++)A[i]=cp((ld)(f[i]&siz),(ld)(f[i]>>15));
        for(int i=0;i<(len>>1);i++)B[i]=cp((ld)(g[i]&siz),(ld)(g[i]>>15));
        FFT(A,len,1),FFT(B,len,1);
        for(int i=0;i<len;i++)
        {
            int j=(len-i)&(len-1);
            C[j]=cp(0.5*(A[i].x+A[j].x),0.5*(A[i].y-A[j].y))*B[i];
            D[j]=cp(0.5*(A[i].y+A[j].y),0.5*(A[j].x-A[i].x))*B[i];
        }
        FFT(C,len,1),FFT(D,len,1);
        for(int i=0;i<len;i++)
        {
            ll tempA=(ll)(C[i].x/len+0.5)%mode;
            ll tempa=(ll)(C[i].y/len+0.5)%mode;
            ll tempB=(ll)(D[i].x/len+0.5)%mode;
            ll tempb=(ll)(D[i].y/len+0.5)%mode;
            re[i]=(ll)(tempA+mode+(ll)((ll)(tempa+tempB)<<15)%mode+mode+(ll)((ll)tempb<<30)%mode+mode)%mode;
        }
    }
    void get_inv(ll *f,ll *g,int dep)
    {
        if(dep==1)
        {
            g[0]=pow_mul(f[0],mode-2);
            return;
        }
        int nxt=(dep)>>1;
        get_inv(f,g,nxt);
        MTT(g,g,tempG,dep);
        MTT(f,tempG,ret,dep<<1);
        for(register int i=0;i<dep;i++)g[i]=(2*g[i]-ret[i]+mode)%mode;
    }
    void get_ln(ll *f,ll *g,int dep)
    {
        get_inv(f,Gg,dep);
        for(int i=1;i<dep;i++)ff[i-1]=f[i]*1ll*i%mode;
        MTT(Gg,ff,ret,dep<<1);
        for(int i=1;i<dep;i++)g[i]=ret[i-1]*pow_mul(i,mode-2)%mode;
    }
    template <typename T>inline void read(T &x)
    {
        int f=1;
        x=0;
        char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        x*=f;
    }
    void print(int x)
    {
        if(!x)return;
        print(x/10);
        putchar('0'+x%10);
    }
    int main()
    {
        read(n),read(mode);
        for(register int i=1;i<=n;i++)read(Ff[i]);
        int Lim=1;
        while(Lim<=n)Lim<<=1,l[Lim]=l[Lim>>1]+1;
        l[Lim<<1]=l[Lim]+1;
        init();
        Ff[0]=1;
        get_ln(Ff,gg,Lim);
        int cnt=0;
        for(register int i=1;i<=n;i++)
        {
            ans[i]=gg[i];
            if(ans[i])cnt++;
            for(register int j=i+i;j<=n;j+=i)gg[j]=(gg[j]-ans[i]*i%mode*inv[j]%mode+mode)%mode;    
        }
        printf("%d
    ",cnt);
        for(register int i=1;i<=n;i++)if(ans[i])print(i),putchar(' ');
        printf("
    ");
        return 0;
    }
  • 相关阅读:
    HDU 5821 Ball (贪心)
    hdu 5826 physics (物理数学,积分)
    HDU 5831 Rikka with Parenthesis II (贪心)
    HDU 2669 Romantic (扩展欧几里得定理)
    POJ 2442 Sequence
    HDU 3779 Railroad(记忆化搜索)
    博客园首页新随笔联系管理订阅 随笔- 524 文章- 0 评论- 20 hdu-5810 Balls and Boxes(概率期望)
    hdu 5813 Elegant Construction (构造)
    hdu 5818 Joint Stacks (优先队列)
    C#字段和属性
  • 原文地址:https://www.cnblogs.com/zhangleo/p/11046259.html
Copyright © 2011-2022 走看看