zoukankan      html  css  js  c++  java
  • CF623E Transforming Sequence

    题目描述:

    luogu

    CF

    题解:

    任意模数$ntt$/奇技淫巧$fft$。

    首先设$f[i][j]$表示在第$i$轮每种有$j$个“1”的01串有$f[i][j]$种生成方式。

    所以答案=$sum f[n][i]*C(k,i)$。

    顺便提一下,$n>k$时$puts("0")$即可。

    然后有这个方程:$$f[x][i]=sum_{j=0}^{i-1}f[x-1][j]*2^j*C(i,j)$$

    拓展一下:$$f[x+y][i] = sum _{j=0} ^{i-1} f[ x ][ j ] * f[ y ][ i-j ]*2 ^ {y*j} * C(i,j)$$

    化成$ntt$形式:$$frac{f[ x+y ][ i ]}{ i! } = sum _{j=0} ^{i-1} frac{f[ x ][ j ] * 2^{y*j} }{ j! } * frac{ 1 }{ (i-j)! }$$

    然后就可以任意模数$ntt$了。

    (或者下面的奇技淫巧$fft$)

    代码:

    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    const long double Pi = acos(-1.0);
    const int MOD = 1000000007;
    const int N = 130050;
    template<typename T>
    inline void read(T&x)
    {
        T f = 1,c = 0;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){c=c*10+ch-'0';ch=getchar();}
        x = f*c;
    }
    ll fastpow(ll x,ll y)
    {
        ll ret = 1;
        while(y)
        {
            if(y&1)ret=ret*x%MOD;
            x=x*x%MOD;
            y>>=1;
        }
        return ret;
    }
    ll inv(ll x){return fastpow(x,MOD-2);}
    ll n,ny[N],jc[N],jny[N],M[N];
    int m;
    struct cp
    {
        long double x,y;
        cp(){}
        cp(long double x,long double y):x(x),y(y){}
        cp operator + (const cp&a)const{return cp(x+a.x,y+a.y);}
        cp operator - (const cp&a)const{return cp(x-a.x,y-a.y);}
        cp operator * (const cp&a)const{return cp(x*a.x-y*a.y,x*a.y+y*a.x);}
    };
    int to[N],lim,L;
    void init()
    {
        lim = 1,L = 0;
        while(lim<=(2*m))lim<<=1,L++;
        for(int i=1;i<lim;i++)to[i] = ((to[i>>1]>>1)|((i&1)<<(L-1)));
        M[0] = ny[1] = jc[0] = jc[1] = jny[0] = jny[1] = 1;
        M[1] = 2;
        for(int i=2;i<=m;i++)
        {
            ny[i] = ((MOD - MOD/i) * ny[MOD%i] %MOD+MOD )%MOD;
            jc[i] = (jc[i-1] * i)%MOD;
            jny[i] = (jny[i-1] * ny[i])%MOD;
            M[i] = (M[i-1] * 2)%MOD;
        }
    }
    ll C(ll x,ll y){return jc[x]*jny[y]%MOD*jny[x-y]%MOD;}
    void fft(cp*a,int len,int k)
    {
        for(int i=0;i<len;i++)
            if(i>to[i])swap(a[i],a[to[i]]);
        for(int i=1;i<len;i<<=1)
        {
            cp w0(cos(Pi/i),k*sin(Pi/i));
            for(int j=0;j<len;j+=(i<<1))
            {
                cp w(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;
                }
            }
        }
        if(k==-1)
            for(int i=0;i<len;i++)a[i].x/=len;
    }
    ll F[N],G[N],H[N];
    cp a[N],b[N],c[N],d[N],e[N],f[N],g[N],h[N];
    void mul(ll y)
    {
        ll K = fastpow(2,y),KK = 1,M = 32768;
        for(int i=0;i<lim;i++)a[i]=b[i]=c[i]=d[i]=cp(0,0);
        for(int i=0;i<=m;i++)
        {
            ll A = G[i]*KK%MOD,B = H[i];
            a[i].x = A/M,b[i].x = A%M;
            c[i].x = B/M,d[i].x = B%M;
            KK = KK*K%MOD;
        }
        fft(a,lim,1),fft(b,lim,1),fft(c,lim,1),fft(d,lim,1);
        for(int i=0;i<lim;i++)
        {
            e[i]=a[i]*c[i],f[i]=b[i]*c[i];
            g[i]=a[i]*d[i],h[i]=b[i]*d[i];
        }
        fft(e,lim,-1),fft(f,lim,-1),fft(g,lim,-1),fft(h,lim,-1);
        for(int i=0;i<lim;i++)
            F[i] = (((ll)(e[i].x+0.1))%MOD*M%MOD*M%MOD + ((ll)(f[i].x+0.1))%MOD*M%MOD 
                    + ((ll)(g[i].x+0.1))%MOD*M%MOD + ((ll)(h[i].x+0.1))%MOD)%MOD;
    }
    ll o[N],s[N];
    void FastFFT()
    {
        ll y = 1;
        for(int i=1;i<=m;i++)o[i]=jny[i];
        s[0] = 1;
        ll N = n;
        while(N)
        {
            if(N&1)
            {
                memcpy(G,s,sizeof(G));
                memcpy(H,o,sizeof(H));
                mul(y);
                memcpy(s,F,sizeof(s));
            }
            memcpy(G,o,sizeof(G));
            memcpy(H,o,sizeof(H));
            mul(y);
            memcpy(o,F,sizeof(o));
            y<<=1,N>>=1;
        }
    }
    int main()
    {
        read(n),read(m);
        init();
        if(n>m)
        {
            puts("0");
            return 0;
        }
        FastFFT();
        ll ans = 0;
        for(int i=n;i<=m;i++)
            (ans+=s[i]*C(m,i)%MOD*jc[i]%MOD)%=MOD;
        printf("%lld
    ",ans);
        return 0;
    }
    View Code
  • 相关阅读:
    python 字符串替换
    python 字符串截取
    python 字符串连接
    PHP 做群发短信(短信接口连接问题)
    Yii dropDownList 下拉菜单 联动菜单
    我的博客即将入驻“云栖社区”,诚邀技术同仁一同入驻。
    SQL Server 2008 R2——分组取前几名
    SQL Server 分组后取Top N
    大型网站架构系列:20本技术书籍推荐
    较主流的消息队列的比较与选型
  • 原文地址:https://www.cnblogs.com/LiGuanlin1124/p/10975795.html
Copyright © 2011-2022 走看看