zoukankan      html  css  js  c++  java
  • 一个人的高三楼

    题目链接:Click here

    Solution:

    题目名字有点伤感啊。。。

    直接看题吧,(k)次前缀和,瞬间想到(O(nk))的做法,20pts到手了,走吧!

    回到正题。。。不难想到,我们构造一个生成函数(G(x)=sum_{i=0}^n x^i),同时有(A(x)=sum_{i=1}^n a_ix^i)

    那么(A imes G)就相当于对(A)做了一次前缀和了,那么(S_n^k=A imes G^k),难道要多项式快速幂?

    多项式快速幂是不可能的,这辈子都不可能的,考虑(G)的特殊性,它的每一项系数都是1

    我们一下子就能发现,(G^k)与组合数的关系,(G^k)的第(i)项的系数就是({i+k-1choose k-1}),不就是插板法吗

    那么我们把(G^k)求出来之后,直接上(NTT)即可

    Code:

    #include<bits/stdc++.h>
    #define int long long 
    #define Pi acos(-1.0)
    using namespace std;
    const int N=4e5+11;
    const int mod=998244353;
    int n,m,k,len=1,tim,p[N];
    int a[N],trans[N],inv[N];
    int read(){
        int x=0,f=1;char ch=getchar();
        while(!isdigit(ch)){if(ch=='-')f=-f;ch=getchar();}
        while(isdigit(ch)){x=x*10+ch-48;ch=getchar();}
        return x*f;
    }
    int qpow(int u,int t){
        int re=1;
        while(t){
            if(t&1) re=re*u%mod;
            t>>=1;u=u*u%mod;
        }return re;
    }
    void NTT(int *v,int flag){
        for(int i=0;i<len;i++)
            if(i<p[i]) swap(v[i],v[p[i]]);
        for(int l=2;l<=len;l<<=1){
            int wn=qpow(3,(mod-1)/l);
            if(flag==-1) wn=qpow(wn,mod-2);
            for(int st=0;st<len;st+=l){
                int w=1;
                for(int u=st;u<st+(l>>1);u++,w=w*wn%mod){
                    int x=v[u],y=w*v[u+(l>>1)]%mod;
                    v[u]=(x+y)%mod;v[u+(l>>1)]=(x-y+mod)%mod;
                }    
            }
        }
    }
    signed main(){
        n=m=read();k=read()%mod;++n;++m;
        for(int i=1;i<n;i++) a[i]=read();
        while(len<=max(n,m)*2) len=len<<1,++tim;
        for(int i=0;i<len;i++)
            p[i]=(p[i>>1]>>1)|((i&1)<<(tim-1));
        trans[0]=1;inv[1]=1;
        for(int i=2;i<=len;i++) inv[i]=inv[mod%i]*(mod-mod/i)%mod;
        for(int i=1;i<m;i++,k=(k+1)%mod) trans[i]=trans[i-1]*k%mod*inv[i]%mod;
        NTT(a,1);NTT(trans,1);
        for(int i=0;i<len;i++) a[i]=a[i]*trans[i]%mod;
        NTT(a,-1);for(int i=0;i<=len;i++) a[i]=a[i]*inv[len]%mod;
        for(int i=1;i<n;i++) printf("%lld
    ",a[i]);
        return 0;
    }
    
    
  • 相关阅读:
    学习DButils笔记
    ubuntu16.04 backup and restore
    Oracle 中 编写 function 和 procedure 的注意事项
    利用反射和JDBC元数据实现更加通用的查询方法
    Memcached
    HTML, CSS
    day35作业
    day34作业
    MySQL数据库
    并发编程
  • 原文地址:https://www.cnblogs.com/NLDQY/p/12239336.html
Copyright © 2011-2022 走看看