# BZOJ #3625 CF #438E 小朋友和二叉树

BZOJ #3625

codeforces #438E

### $Solution$

$f[0]=1$

$f[x]=\sum\limits_{i=0}^x \sum\limits_{j=0}^{x-i}f[i]f[j]·[C[x-i-j]=1]$

$f=C·f^2+1$

$f=\frac{1 \pm \sqrt{1-4C}}{2C}$

$f=\frac{1 - \sqrt{1-4C}}{2C}$

$f=\frac{2}{1+\sqrt{1-4C}}$

### $my \ code$

#include<ctime>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
#define rt register int
#define ll long long
using namespace std;
namespace fast_IO{
const int IN_LEN=10000000,OUT_LEN=10000000;
char ibuf[IN_LEN],obuf[OUT_LEN],*ih=ibuf+IN_LEN,*oh=obuf,*lastin=ibuf+IN_LEN,*lastout=obuf+OUT_LEN-1;
inline void putchar_(const char x){if(oh==lastout)fwrite(obuf,1,oh-obuf,stdout),oh=obuf;*oh++=x;}
inline void flush(){fwrite(obuf,1,oh-obuf,stdout);}
}
using namespace fast_IO;
//#define getchar() getchar_()
//#define putchar(x) putchar_((x))
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('\n');}
int k,m,n,x,y,z,cnt,ans;

namespace poly{
#define p 998244353
vector<int>R;
vector<int>get(int n){
vector<int>ret(n);
return ret;
}
void print(const vector<int>A){for(rt i=0;i<A.size();i++)write((A[i]+p)%p),putchar(' ');}
int ksm(int x,int y=p-2){
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 NTT(int n,vector<int>&A,int fla){
A.resize(n);
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);
for(rt i=0;i<n;i++)A[i]=1ll*A[i]*invn%p;
}
}
vector<int>Resize(int n,vector<int>A){A.resize(n);return A;}
vector<int>Mul(vector<int>x,vector<int>y){
int lim=1,sz=x.size()+y.size()-1;
while(lim<=sz)lim<<=1;R.resize(lim);
for(rt i=0;i<lim;i++)R[i]=(R[i>>1]>>1)|(i&1)*(lim>>1);
NTT(lim,x,1);NTT(lim,y,1);
for(rt i=0;i<lim;i++)x[i]=1ll*x[i]*y[i]%p;
NTT(lim,x,-1);x.resize(sz);
return x;
}
vector<int>Inv(vector<int>A,int n=-1){
if(n==-1)n=A.size();
if(n==1)return vector<int>(1,ksm(A[0]));
vector<int>b=Inv(A,(n+1)/2);
int lim=1;while(lim<=n+n)lim<<=1;R.resize(lim);
for(rt i=0;i<lim;i++)R[i]=(R[i>>1]>>1)|(i&1)*(lim>>1);
A.resize(n);NTT(lim,A,1);NTT(lim,b,1);
for(rt i=0;i<lim;i++)A[i]=1ll*b[i]*(2ll-1ll*A[i]*b[i]%p)%p;
NTT(lim,A,-1);A.resize(n);
return A;
}
vector<int>Div(vector<int>A,vector<int>B){
int n=A.size(),m=B.size();
reverse(A.begin(),A.end());
reverse(B.begin(),B.end());
A.resize(n-m+1),B.resize(n-m+1);
int lim=1;while(lim<=2*(n-m+1))lim<<=1;R.resize(lim);
for(rt i=0;i<lim;i++)R[i]=(R[i>>1]>>1)|(i&1)*(lim>>1);
vector<int>ans=Resize(n-m+1,Mul(A,Inv(B)));
reverse(ans.begin(),ans.end());
return ans;
}
int len=max(A.size(),B.size());A.resize(len);
for(rt i=0;i<len;i++)(A[i]+=B[i])%=p;
return A;
}
vector<int>Sub(vector<int>A,vector<int>B){
int len=max(A.size(),B.size());A.resize(len);
for(rt i=0;i<len;i++)(A[i]-=B[i])%=p;
return A;
}
vector<int>Mul(int x,vector<int>A){
for(rt i=0;i<A.size();i++)A[i]=1ll*A[i]*x%p;
return A;
}
vector<int>deriv(vector<int>A){//求导
for(rt i=1;i<A.size();i++)(A[i-1]=1ll*A[i]*i%p);
A.pop_back();return A;
}
vector<int>integ(vector<int>A){//积分
A.push_back(0);
for(rt i=A.size()-2;i>=0;i--)A[i+1]=1ll*A[i]*ksm(i+1)%p;
A[0]=0;return A;
}
vector<int>Ln(const vector<int>A){return integ(Resize(A.size()-1,Mul(deriv(A),Inv(A))));}
vector<int>Exp(vector<int>A,int n=-1){
if(n==-1)n=A.size();
if(n==1)return vector<int>(1,1);
vector<int>A0=Resize(n,Exp(A,(n+1)>>1));
vector<int>now=Resize(n,Ln(A0));
for(rt i=0;i<n;i++)now[i]=(A[i]-now[i])%p;now[0]++;
return Resize(n,Mul(A0,now));
}
struct cp{
ll a,b,z;//a+bsqrt(z)
cp operator *(const cp s)const{
return {(1ll*a*s.a%p+1ll*b*s.b%p*z%p)%p,(1ll*a*s.b%p+1ll*b*s.a)%p,z};
}
};
cp ksm(cp x,int y){
cp ans={1,0,x.z};
for(rt i=y;i;i>>=1,x=x*x)if(i&1){
ans=x*ans;
}
return ans;
}
int Sqrt(int n){//求二次剩馀
if(ksm(n,(p-1)/2)!=1)return -1;
while(1){
x=rand()%p;
if(ksm((1ll*x*x%p-n%p+p)%p,(p-1)/2)==1)continue;
cp ret=ksm({x,1,(1ll*x*x%p+p-n)%p},(p+1)/2);
return min(ret.a,p-ret.a);
}
}
vector<int>GetSqrt(vector<int>A,int n=-1){
if(n==-1)n=A.size();
if(n==1)return vector<int>(1,Sqrt(A[0]));
vector<int>ans=Resize(n,GetSqrt(A,n+1>>1)),C(A.begin(),A.begin()+n);
}
vector<int>Pow(vector<int>A,int k){
A[0]=1;
return Exp(Mul(k,Ln(A)));
}
//#undef p
};
using namespace poly;
int inv[100010],v[100010];
int main(){
vector<int>c(n+1);
for(rt i=1;i<=m;i++){
if(x<=n)c[x]++;
}
vector<int>ans=Mul(-4,c);ans[0]++;
ans=GetSqrt(ans);ans[0]++;
ans=Mul(2,Inv(ans));
for(rt i=1;i<=n;i++)writeln((ans[i]+p)%p);
return flush(),0;
}

posted @ 2018-12-26 08:45  Kananix  阅读(...)  评论(...编辑  收藏