• 【51nod 1514】 美妙的序列


    题目

    我们发现我们得正难则反

    还是设(f_i)表示长度为(i)的序列个数

    考虑容斥

    [f_i=i!-sum_{j=1}^{i-1}f_j(i-j)! ]

    (i!)显然是总方案数,我们减掉不合法的方案数,显然(1)(j)这些数强行合法,之后(j+1)(i)在后面自由排列,由于在(j)后面这个位置没有一个数比之前的小,所以一定不合法,同时通过首次不合法的位置区分开不同的序列,从而做到不重不漏

    但是上面有一个小问题就是(f_0=0),但是按照上面的递推数列来推会造成(f_0=1)

    于是应该写成

    [f_i=i!-sum_{j=1}^{i-1}f_j(i-j)!-[i=0] ]

    也就是

    [sum_{j=1}^if_j(i-j)!=i!-[i=0] ]

    设阶乘的生成函数是(G(x))

    就有

    [F(x) imes G(x)=G(x)-1 ]

    [F(x)=frac{G(x)-1}{G(x)}=1-frac{1}{G(x)} ]

    也就是对阶乘求一个逆

    代码

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define re register
    #define LL long long
    #define max(a,b) ((a)>(b)?(a):(b))
    #define min(a,b) ((a)<(b)?(a):(b))
    const int maxn=261244+1005;
    inline int read() {
    	char c=getchar();int x=0;while(c<'0'||c>'9') c=getchar();
    	while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();return x;
    }
    const LL G[2]={3,332748118};
    const LL mod=998244353;
    LL fac[maxn],K[maxn],D[maxn],C[maxn],A[maxn],B[maxn];
    int n,rev[maxn],ask[maxn],len,T;
    inline LL ksm(LL a,LL b) {LL S=1;while(b) {if(b&1) S=S*a%mod;b>>=1;a=a*a%mod;}return S;}
    inline void NTT(LL *f,int o) {
    	for(re int i=0;i<len;i++) if(i<rev[i]) std::swap(f[i],f[rev[i]]);
    	for(re int i=2;i<=len;i<<=1) {
    		int ln=i>>1;LL og1=ksm(G[o],(mod-1)/i);
    		for(re int l=0;l<len;l+=i) {
    			LL t,og=1;
    			for(re int x=l;x<l+ln;x++) {
    				t=(og*f[ln+x])%mod;
    				f[ln+x]=(f[x]-t+mod)%mod;
    				f[x]=(f[x]+t)%mod;
    				og=(og*og1)%mod;
    			}
    		}
    	}
    	if(!o) return;
    	LL inv=ksm(len,mod-2);
    	for(re int i=0;i<len;i++) f[i]=(f[i]*inv)%mod;
    }
    inline void mul(int n,LL *A,LL *B) {
    	len=1;while(len<n+n) len<<=1;
    	for(re int i=0;i<len;i++) rev[i]=rev[i>>1]>>1|((i&1)?len>>1:0);
    	NTT(A,0),NTT(B,0);for(re int i=0;i<len;i++) A[i]=(A[i]*B[i])%mod;
    	NTT(A,1);for(re int i=n;i<len;i++) A[i]=0;
    }
    inline void Inv(int n,LL *A,LL *B) {
    	if(n==1) {B[0]=ksm(A[0],mod-2);return;}
    	Inv((n+1)>>1,A,B);
    	memset(C,0,sizeof(C));memset(D,0,sizeof(D));memset(K,0,sizeof(K));
    	for(re int i=0;i<n;i++) C[i]=K[i]=B[i],D[i]=A[i];
    	mul(n,C,K);mul(n,C,D);
    	for(re int i=0;i<n;i++) B[i]=(2ll*B[i]-C[i]+mod)%mod;
    }
    int main() {
    	T=read();
    	for(re int i=1;i<=T;i++) 
    		ask[i]=read(),n=max(n,ask[i]+1);
    	A[0]=1;for(re int i=1;i<n;i++) A[i]=(A[i-1]*1ll*i)%mod;
    	Inv(n,A,B);
    	for(re int i=0;i<n;i++) B[i]=(mod-B[i])%mod;B[0]++;
    	for(re int i=1;i<=T;i++) printf("%lld
    ",B[ask[i]]); 
    	return 0;
    }
    
    
  • 相关阅读:
    putty远程登录,no supported authentication methods available解决方法(腾讯云)
    spring boot 集成 springbootstarterquartz 集群版配置
    排序算法
    密码发生器
    分解质因数
    python基础面试题
    计算输入密码的时间
    论文解读(GCC)《Efficient Graph Convolution for Joint Node RepresentationLearning and Clustering》 Learner
    期望、方差、协方差 Learner
    论文解读(LGAE)《Simple and Effective Graph Autoencoders with OneHop Linear Models》 Learner
  • 原文地址:https://www.cnblogs.com/asuldb/p/10550824.html
Copyright © 2020-2023  润新知