zoukankan      html  css  js  c++  java
  • 【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;
    }
    
    
  • 相关阅读:
    还需要做恰当的解读,此时你可能需要一些书:
    创业公司的架构演进史
    任务调度平台Cuckoo-Schedule
    ORACLE中死锁
    Action的模型绑定
    三次握手、四次握手、backlog
    Django框架
    扩展BootstrapTable的treegrid功能
    Identity Service
    Linux权限
  • 原文地址:https://www.cnblogs.com/asuldb/p/10550824.html
Copyright © 2011-2022 走看看