• [CF438E]The Child and Binary Tree


    description

    题面

    我们的小朋友很喜欢计算机科学,而且尤其喜欢二叉树。
    考虑一个含有(n)个互异正整数的序列(c[1],c[2],...,c[n])
    如果一棵带点权的有根二叉树满足其所有顶点的权值都在集合({c[1],c[2],...,c[n]})中,我们的小朋友就会将其称作神犇的。
    并且他认为,一棵带点权的树的权值,是其所有顶点权值的总和。 给出一个整数m,你能对于任意的s(1<=s<=m)计算出权值为s的神犇二叉树的个数吗?
    请参照样例以更好的理解什么样的两棵二叉树会被视为不同的。 我们只需要知道答案关于998244353取模后的值。

    data range

    [1≤n,m≤100000 ]

    solution

    (f_i)表示权值为(i)的神犇二叉树的个数
    (F(x)=sum_{i=0}^{n}f_ix^i)(C(x)=sum_{i=0}^{n}c_ix_i),那么有

    [F^2C=F^2+F-1 ]

    解方程,得

    [F=frac{1pmsqrt{5-4C}}{2C-2}=frac{4C-4}{(2C-2)(1mpsqrt{5-4C})}=frac{2}{1mpsqrt{5-4C}} ]

    因为取负号时多项式分母可能为(0),因此最终答案中的负号舍去,即

    [F=frac{2}{1+sqrt{5-4C}} ]

    多项式开方+多项式求逆即可

    code

    #include<bits/stdc++.h>
    #include<algorithm>
    #include<iostream>
    #include<cstdlib>
    #include<iomanip>
    #include<cstring>
    #include<complex>
    #include<vector>
    #include<cstdio>
    #include<string>
    #include<bitset>
    #include<ctime>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<map>
    #include<set>
    #define FILE "a"
    #define mp make_pair
    #define pb push_back
    #define RG register
    #define il inline
    using namespace std;
    typedef unsigned long long ull;
    typedef vector<int>VI;
    typedef long long ll;
    typedef double dd;
    const dd eps=1e-10;
    const int mod=998244353;
    const int N=1000010;
    const dd pi=acos(-1);
    const int inf=2147483647;
    const ll INF=1e18+1;
    const ll P=100000;
    il ll read(){
    	RG ll data=0,w=1;RG char ch=getchar();
    	while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
    	if(ch=='-')w=-1,ch=getchar();
    	while(ch<='9'&&ch>='0')data=data*10+ch-48,ch=getchar();
    	return data*w;
    }
    
    il void file(){
    	srand(time(NULL)+rand());
    	freopen(FILE".in","r",stdin);
    	freopen(FILE".out","w",stdout);
    }
    
    il int poww(int a,int b){
    	RG int ret=1;
    	for(;b;b>>=1,a=1ll*a*a%mod)
    		if(b&1)ret=1ll*ret*a%mod;
    	return ret;
    }
    
    int l,r[N];
    il void NTT(int *a,int n,int opt){
    	for(l=1;(1<<l)<n;l++);n=(1<<l);
    	for(RG int i=0;i<n;i++)r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));
    	for(RG int i=0;i<n;i++)if(i<r[i])swap(a[i],a[r[i]]);
    	for(RG int i=2;i<=n;i<<=1){
    		RG int wn=poww(opt==1?3:(mod+1)/3,(mod-1)/i);
    		for(RG int j=0;j<n;j+=i){
    			RG int w=1;
    			for(RG int k=j;k<j+(i>>1);k++,w=1ll*w*wn%mod){
    				RG int x=1ll*a[k+(i>>1)]*w%mod;
    				a[k+(i>>1)]=(a[k]-x+mod)%mod;
    				a[k]=(a[k]+x)%mod;
    			}
    		}
    	}
    	if(opt==-1)
    		for(RG int i=0,rv=poww(n,mod-2);i<n;i++)
    			a[i]=1ll*a[i]*rv%mod;
    }
    
    int a[N],b[N];
    il void getinv(int *f,int *g,int n){
    	if(n==1){g[0]=poww(f[0],mod-2);return;}getinv(f,g,n>>1);
    	for(RG int i=0;i<n;i++)a[i]=f[i];
    	for(RG int i=0;i<(n>>1);i++)b[i]=g[i];
    	NTT(a,n<<1,1);NTT(b,n<<1,1);
    	for(RG int i=0;i<(n<<1);i++)
    		b[i]=1ll*(2-1ll*a[i]*b[i]%mod+mod)%mod*b[i]%mod;
    	NTT(b,n<<1,-1);
    	for(RG int i=0;i<n;i++)g[i]=b[i];
    	for(RG int i=0;i<(n<<1);i++)a[i]=b[i]=0;
    }
    
    int c[N],d[N];
    il void getsqrt(int *f,int *g,int n){
    	if(n==1){g[0]=sqrt(f[0]);return;}getsqrt(f,g,n>>1);	
    	for(RG int i=0;i<n;i++)c[i]=f[i];
    	getinv(g,d,n>>1);
    	NTT(c,n<<1,1);NTT(d,n<<1,1);
    	for(RG int i=0;i<(n<<1);i++)c[i]=1ll*c[i]*d[i]%mod;
    	NTT(c,n<<1,-1);
    	for(RG int i=0;i<n;i++)
    		g[i]=1ll*(c[i]+g[i])%mod*((mod+1)/2)%mod;
    	for(RG int i=0;i<(n<<1);i++)c[i]=d[i]=0;
    }
    
    int s,n,m,f[N],g[N],len;
    il int upd(int a,int b){a+=b;if(a>=mod)a-=mod;return a;}
    il int dec(int a,int b){if(!b)return a;else return upd(a,mod-b);}
    il int mul(int a,int b){return 1ll*a*b%mod;}
    
    int main()
    {
    	s=read();m=read();
    	for(RG int i=1,x;i<=s;i++)f[x=read()]=1,n=max(n,x);
    	for(len=1;len<=max(n,m);len<<=1);
    	for(RG int i=1;i<=n;i++)f[i]=dec(0,mul(4,f[i]));f[0]=1;
    	getsqrt(f,g,len<<1);
    	g[0]=2;memset(f,0,sizeof(f));
    	getinv(g,f,len);
    	for(RG int i=1;i<=m;i++)printf("%lld
    ",2ll*f[i]%mod);
    	return 0;
    }
    
    
  • 相关阅读:
    在 Eclipse Workbench 之外使用 Eclipse GUI
    GB2312,GBK,Unicode
    木偶一之推荐系统
    Matlab:任意矩阵计算分布密度(海明距离的分布密度)
    live555在arm linux下的交叉编译,并下载的Arm板播放H264文件
    java设计模式之原型模式
    HDU 1102
    poj3661另一种做法(滚动数组)
    基于QT的小游戏细菌病毒战
    某代码查看器的保护突破
  • 原文地址:https://www.cnblogs.com/cjfdf/p/9332374.html
Copyright © 2020-2023  润新知