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

    生成函数和组合数学的灵活应用

    LOJ #6261

    题意:求一个数列的$ k$次前缀和


    $ Solution:$

    我们对原数列$ a$建生成函数$ A=sumlimits_{i=0}^{n-1} a_ix^i $

    求一次前缀和相当于将$ A$卷上生成函数$ B=sumlimits_{i=0}^{n-1}x^i pmod{x^n}$

    即我们要求的就是$ A·B^{k-1} pmod{x^n}$

    直接快速幂是$ log^2$的,但是生成函数$ B$有一些巧妙的性质:

    $ B^k(x)$的意义是选$ k$个自然数使得和为$ x$

    可以通过插板法得知$ B^k(x)$=$ C_{x+k}^x$

    然后求出$ A,B$之后$ NTT$卷积即可

    时间复杂度:$ O(n log n)$


     $ my code:$

    #include<ctime>
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<queue>
    #define p 998244353 
    #define rt register int
    #define ll long long
    using namespace std;
    inline ll read(){
        ll x = 0; char zf = 1; char ch = getchar();
        while (ch != '-' && !isdigit(ch)) ch = getchar();
        if (ch == '-') zf = -1, ch = getchar();
        while (isdigit(ch)) x = x * 10 + ch - '0', ch = getchar(); return x * zf;
    }
    void write(ll y){if(y<0)putchar('-'),y=-y;if(y>9)write(y/10);putchar(y%10+48);}
    void writeln(const ll y){write(y);putchar('
    ');}
    int i,j,k,n,x,y,z,cnt,lim,m;
    vector<int>A,B,R;
    int inv[100010];
    int ksm(int x,int y){
        int ans=1;
        for(rt i=y;i;i>>=1,x=1ll*x*x%p)if(i&1)ans=1ll*ans*x%p;
        return ans;
    }
    void init(){
        lim=1;while(lim<=n+n)lim*=2;
        A.resize(lim);B.resize(lim);R.resize(lim);
        for(rt i=1;i<lim;i++)R[i]=(R[i>>1]>>1)|(i&1)*(lim>>1);
        for(rt i=0;i<n;i++)A[i]=read();
        inv[0]=inv[1]=1;B[0]=1;
        for(rt i=2;i<=n;i++)inv[i]=1ll*inv[p%i]*(p-p/i)%p;
        for(rt i=1;i<n;i++)B[i]=1ll*(i+m)*B[i-1]%p*inv[i]%p;
    }
    void NTT(int n,vector<int>&A,int fla){
        for(rt i=0;i<n;i++)if(i>R[i])swap(A[i],A[R[i]]);
        for(rt i=1;i<n;i<<=1){
            int w=ksm(3,(p-1)/2/i);
            for(rt j=0;j<n;j+=i<<1){
                int K=1;
                for(rt k=0;k<i;k++,K=1ll*K*w%p){
                    int x=A[j+k],y=1ll*K*A[i+j+k]%p;
                    A[j+k]=(x+y)%p,A[i+j+k]=(x-y)%p;
                }
            }
        }
        if(fla==-1){
            reverse(A.begin()+1,A.end());int invn=ksm(n,p-2);
            for(rt i=0;i<n;i++)A[i]=1ll*A[i]*invn%p;    
        }
    }
    int main(){
        n=read();m=(read()-1)%p;init();
        NTT(lim,A,1);NTT(lim,B,1);
        for(rt i=0;i<lim;i++)A[i]=1ll*A[i]*B[i]%p;
        NTT(lim,A,-1);
        for(rt i=0;i<n;i++)writeln((A[i]+p)%p);
        return 0;
    }
  • 相关阅读:
    【NLP之文本摘要】4_oov和word repetition问题
    【文本摘要项目】5性能提升之PGN模型
    案例学习Transformer 及其实现细节]
    【NLP之文本摘要】3NLG过程及其优化与模型评估
    案例学习理解语言的 Transformer 模型
    【文本摘要项目】4解码算法及模型测试结果评估
    【NLP之文本摘要】5_transformer模型初级探索
    【文本摘要项目】6性能提升之Transformer模型
    【文本摘要项目】7性能提升之基于Transformer的PGN模型
    指针作为参数传入函数的陷阱
  • 原文地址:https://www.cnblogs.com/DreamlessDreams/p/10056752.html
Copyright © 2011-2022 走看看