4555: [Tjoi2016&Heoi2016]求和
第二类斯特林数是把n个物品分到x个无标号盒子的方案数
那么$s(i,j)*(j!)$就是把n个物品分到x个有标号的盒子的方案数
$f(n)=sum _{j=1}^{n}s(n,j)*(j!)$
$f(n)$即把n个物品分到任意个有标号盒子的方案数
$f(i)=sum_{j=1}^{i}C(i,j)*f(i-j)$ 枚举最后一个盒子装的球的个数
$f(n)=sum _{j=1}^{n}s(n,j)*(j!)*(2^j)$
$f(i)=2*sum_{j=1}^{i}C(i,j)*f(i-j)$ 多一个盒子
$f(i)/i!= sum_{j=1}^{i}2/j!*f(i-j)/(i-j)!$
$设F(i)=f(i)/i!$
$f(i)=2/i!$
$f=f*g+1$
$(f(0)=1)$
$f=1/(1-g)$
多项式求逆即可
1 //Achen
2 #include<algorithm>
3 #include<iostream>
4 #include<cstring>
5 #include<cstdlib>
6 #include<vector>
7 #include<cstdio>
8 #include<queue>
9 #include<cmath>
10 #include<set>
11 #include<map>
12 #define For(i,a,b) for(int i=(a);i<=(b);i++)
13 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
14 const int N=4e5+7,p=998244353,gg=3,gi=332748118;
15 typedef long long LL;
16 typedef double db;
17 using namespace std;
18 int n;
19 LL f[N],g[N];
20
21 template<typename T> void read(T &x) {
22 char ch=getchar(); x=0; T f=1;
23 while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
24 if(ch=='-') f=-1,ch=getchar();
25 for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
26 }
27
28 LL ksm(LL a,LL b) {
29 LL rs=1,bs=a%p;
30 while(b) {
31 if(b&1) rs=rs*bs%p;
32 bs=bs*bs%p;
33 b>>=1;
34 }
35 return rs;
36 }
37
38 int r[N];
39 void FFT(LL a[],int n,int l,int f) {
40 For(i,0,n-1) r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));
41 For(i,0,n-1) if(i<r[i]) swap(a[i],a[r[i]]);
42 for(int i=1;i<n;i<<=1) {
43 LL wn=ksm((f==1?gg:gi),(p-1)/(i<<1));
44 for(int j=0,pp=(i<<1);j<n;j+=pp) {
45 LL w=1;
46 for(int k=0;k<i;k++,w=w*wn%p) {
47 LL x=a[j+k],y=w*a[j+k+i]%p;
48 a[j+k]=(x+y)%p; a[j+k+i]=(x-y+p)%p;
49 }
50 }
51 }
52 if(f==-1) {
53 LL inv=ksm(n,p-2);
54 For(i,0,n-1) a[i]=a[i]*inv%p;
55 }
56 }
57
58 LL tp[N],inv[N],fac[N];
59 void get_inv(LL a[],LL b[],int n,int l) {
60 if(n==1) {
61 b[0]=ksm(a[0],p-2);
62 return;
63 }
64 get_inv(a,b,n>>1,l-1);
65 For(i,0,n-1) tp[i]=a[i],tp[i+n]=0;
66 FFT(tp,(n<<1),l+1,1);
67 FFT(b,(n<<1),l+1,1);
68 For(i,0,(n<<1)) tp[i]=(2LL-tp[i]*b[i]%p+p)%p*b[i]%p;
69 FFT(tp,(n<<1),l+1,-1);
70 For(i,0,n-1) b[i]=tp[i],b[i+n]=0;
71 }
72
73 //#define DEBUG
74 int main() {
75 #ifdef DEBUG
76 freopen("1.in","r",stdin);
77 //freopen(".out","w",stdout);
78 #endif
79 read(n);
80 inv[0]=inv[1]=1; fac[0]=1;
81 For(i,2,n) inv[i]=p-p/i*inv[p%i]%p;
82 For(i,1,n) fac[i]=fac[i-1]*i%p,inv[i]=inv[i-1]*inv[i]%p;
83 For(i,1,n) g[i]=(p-2LL*inv[i]%p)%p; g[0]=1;
84 int nn=1,ll=0;
85 for(;nn<=n+1;nn<<=1) ll++;
86 get_inv(g,f,nn,ll);
87 LL ans=0;
88 For(i,0,nn-1) ans=(ans+f[i]*fac[i])%p;
89 printf("%lld
",ans%p);
90 return 0;
91 }
3456: 城市规划
求n个点的简单(无重边无自环)无向连通图数目.
$f(n)表示n个点的简单无向图的个数$
$f(n)=2^{C(n,2)}$
$g(n)表示n个点的简单无向连通图的个数$
$f(n)=sum_{i=1}^nC(n-1,i-1)*g(i)*f(n-i)$
(枚举1所在联通块的大小)
$f(n)/(n-1)!=sum_{i=1}^ng(i)/(i-1)!*f(n-i)/(n-i)!$
$设F(n)=f(n)/(n-1)$
$G(n)=g(n)/(n-1)!$
$H(n)=f(n)/n!$
$F=G*H$
$G=F/H$
多项式求逆
1 //Achen
2 #include<algorithm>
3 #include<iostream>
4 #include<cstring>
5 #include<cstdlib>
6 #include<vector>
7 #include<cstdio>
8 #include<queue>
9 #include<cmath>
10 #include<set>
11 #include<map>
12 const int N=1621470,p=1004535809,gg=3,gi=334845270;
13 #define For(i,a,b) for(int i=(a);i<=(b);i++)
14 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
15 typedef long long LL;
16 typedef double db;
17 using namespace std;
18 int n;
19 LL g[N],h[N],h_inv[N],fac[N],inv[N];
20
21 template<typename T> void read(T &x) {
22 char ch=getchar(); x=0; T f=1;
23 while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
24 if(ch=='-') f=-1,ch=getchar();
25 for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
26 }
27
28 LL ksm(LL a,LL b) {
29 LL rs=1,bs=a%p;
30 while(b) {
31 if(b&1) rs=rs*bs%p;
32 bs=bs*bs%p;
33 b>>=1;
34 }
35 return rs;
36 }
37
38
39 int r[N];
40 void FFT(LL a[],int n,int l,int f) {
41 For(i,0,n-1) r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));
42 For(i,0,n-1) if(i<r[i]) swap(a[i],a[r[i]]);
43 for(int i=1;i<n;i<<=1) {
44 LL wn=ksm((f==1?gg:gi),(p-1)/(i<<1));
45 for(int j=0,pp=(i<<1);j<n;j+=pp) {
46 LL w=1;
47 for(int k=0;k<i;k++,w=w*wn%p) {
48 LL x=a[j+k],y=w*a[j+k+i]%p;
49 a[j+k]=(x+y)%p; a[j+k+i]=(x-y+p)%p;
50 }
51 }
52 }
53 if(f==-1) {
54 LL inv=ksm(n,p-2);
55 For(i,0,n-1) a[i]=a[i]*inv%p;
56 }
57 }
58
59 LL tp[N];
60 void get_inv(LL a[],LL b[],int n,int l) {
61 if(n==1) {
62 b[0]=ksm(a[0],p-2);
63 return;
64 }
65 get_inv(a,b,n>>1,l-1);
66 For(i,0,n-1) tp[i]=a[i],tp[i+n]=0;
67 FFT(tp,(n<<1),l+1,1);
68 FFT(b,(n<<1),l+1,1);
69 For(i,0,(n<<1)) tp[i]=(2LL-tp[i]*b[i]%p+p)%p*b[i]%p;
70 FFT(tp,(n<<1),l+1,-1);
71 For(i,0,n-1) b[i]=tp[i],b[i+n]=0;
72 }
73
74 LL C(int n,int m) { if(m<0||n<m) return 0; return fac[n]*inv[m]%p*inv[n-m]%p; }
75
76 //#define DEBUG
77 int main() {
78 #ifdef DEBUG
79 freopen("1.in","r",stdin);
80 //freopen(".out","w",stdout);
81 #endif
82 read(n);
83 fac[0]=1; inv[0]=inv[1]=1;
84 For(i,2,n+1) inv[i]=p-p/i*inv[p%i]%p;
85 For(i,1,n+1) fac[i]=fac[i-1]*i%p,inv[i]=inv[i-1]*inv[i]%p;
86 For(i,0,n) {
87 LL tp=ksm(2,((LL)i*(i-1)/2)%(p-1));
88 if(i) g[i]=tp*inv[i-1]%p;
89 h[i]=tp*inv[i]%p;
90 }
91 //For(i,0,n) printf("%lld ",g[i]); puts("");
92 //For(i,0,n) printf("%lld ",h[i]); puts("");
93 int nn=1,ll=0;
94 for(;nn<=2*(n+1);nn<<=1) ll++;
95 get_inv(h,h_inv,nn>>1,ll-1);
96 //For(i,0,n) printf("%lld ",h_inv[i]); puts("");
97 FFT(h_inv,nn,ll,1); FFT(g,nn,ll,1);
98 For(i,0,nn) g[i]=g[i]*h_inv[i]%p;
99 FFT(g,nn,ll,-1);
100 //For(i,0,100) printf("%lld ",g[i]); puts("");
101 printf("%lld
",g[n]*fac[n-1]%p);
102 return 0;
103 }
3625: [Codeforces Round #250]小朋友和二叉树
$设c的生成函数为g$
$神犇二叉树的个数的生成函数为f$
$有f=f*f*g+1$ (空节点)
$f=(1+sqrt(1-4*g))/2*g$
$或f=(1-sqrt(1-4*g))/2*g$
$g(0)=0(c>1),所以上面1的常数项一定是取减号后抵消了$
$f=(1+sqrt(1-4*g))/2*g$
多项式开根。
牛顿迭代。
因为常数不优秀,cf上可以过,bz上会t
//Achen
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<queue>
#include<cmath>
#include<set>
#include<map>
#define For(i,a,b) for(int i=(a);i<=(b);i++)
#define Rep(i,a,b) for(int i=(a);i>=(b);i--)
const int N=4e5+7,p=998244353,gg=3,gi=332748118;
typedef long long LL;
typedef double db;
using namespace std;
int n,m;
LL h[N],g[N],inv_2;
template<typename T> void read(T &x) {
char ch=getchar(); x=0; T f=1;
while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-') f=-1,ch=getchar();
for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
}
LL ksm(LL a,LL b) {
LL rs=1,bs=a%p;
while(b) {
if(b&1) rs=rs*bs%p;
bs=bs*bs%p;
b>>=1;
}
return rs;
}
void FFT(LL a[],int n,int l,int f) {
static int r[N];
For(i,0,n-1) r[i]=(r[i>>1]>>1)|((i&1)<<l-1);
For(i,0,n-1) if(i<r[i]) swap(a[i],a[r[i]]);
for(int i=1;i<n;i<<=1) {
LL wn=ksm((f==1?gg:gi),(p-1)/(i<<1));
for(int j=0,pp=(i<<1);j<n;j+=pp) {
LL w=1;
for(int k=0;k<i;k++,w=w*wn%p) {
LL x=a[j+k]%p,y=a[j+k+i]*w%p;
a[j+k]=(x+y)%p,a[j+k+i]=(x-y+p)%p;
}
}
}
if(f==-1) {
LL invv=ksm(n,p-2);
For(i,0,n-1) a[i]=a[i]*invv%p;
}
}
LL tp[N],h_inv[N];
void get_inv(LL a[],LL b[],int n,int l) {
if(n==1) {
b[0]=ksm(a[0],p-2);
return ;
}
get_inv(a,b,n>>1,l-1);
For(i,0,n-1) tp[i]=a[i],tp[i+n]=0;
FFT(tp,n<<1,l+1,1);
FFT(b,n<<1,l+1,1);
For(i,0,n<<1) tp[i]=(2LL-tp[i]*b[i]%p+p)%p*b[i]%p;
FFT(tp,n<<1,l+1,-1);
For(i,0,n-1) b[i]=tp[i],b[i+n]=0;
}
LL h_sqr[N],a_t[N],b_t[N];
void get_sqr(LL a[],LL b[],int n,int l) {
if(n==1) {
b[0]=sqrt(a[0]);
return;
}
get_sqr(a,b,n>>1,l-1);
For(i,0,n<<1) b_t[i]=0;
For(i,0,n-1) a_t[i]=a[i],a_t[i+n]=0;
get_inv(b,b_t,n,l);
FFT(b,n<<1,l+1,1);
FFT(a_t,n<<1,l+1,1);
FFT(b_t,n<<1,l+1,1);
For(i,0,n<<1) b[i]=(b[i]+a_t[i]*b_t[i]%p)%p*inv_2%p;
FFT(b,n<<1,l+1,-1);
For(i,0,n-1) b[n+i]=0;
}
//#define DEBUG
int main() {
#ifdef DEBUG
freopen("1.in","r",stdin);
//freopen(".out","w",stdout);
#endif
read(n); read(m);
inv_2=ksm(2,p-2);
For(i,1,n) {
int x; read(x); g[x]++;
}
h[0]=1;
For(i,1,m) if(g[i]) h[i]=(p-4LL*g[i]%p)%p;
int nn=1,ll=0;
for(;nn<=m+1;nn<<=1) ll++;
get_sqr(h,h_sqr,nn,ll);
h_sqr[0]=(h_sqr[0]+1)%p;
get_inv(h_sqr,h_inv,nn,ll);
For(i,1,m) printf("%I64d
",(h_inv[i]+h_inv[i])%p);
return 0;
}
我真是蠢到不行,遇见式子不要感觉有一点不对劲就盯着它发呆,你好歹去把它化一化啊,多半化一化就出来了,脑子是木的吗我。
4.27
3684: 大朋友和多叉树
第一次写多项式的题写完--虽然写了很久--就过了样例然后1a了,感觉生活又充满了希望
拉格朗日反演:
若$G(f(x))=x$
$[x^n]f(x)=frac{1}{n}[x^{n-1}](frac{x}{G(x)})^n$
证明是什么,不好吃吧
$f为答案的生成函数$
$f(x)=sum_{k in d}f^k(x)+x$
$f(0)=0$
$f(x)-sum_{k in d}f^k(x)=x$
$G(f(x))=f(x)-sum_{k in d}f^k(x)$
$G(x)=x-sum_{k in d}x^k$
套用反演公式即可
$f(x)^k=e^{k*lnf(x)}$
1 //Achen 2 #include<algorithm> 3 #include<iostream> 4 #include<cstring> 5 #include<cstdlib> 6 #include<vector> 7 #include<cstdio> 8 #include<queue> 9 #include<cmath> 10 #include<set> 11 #include<map> 12 #define For(i,a,b) for(int i=(a);i<=(b);i++) 13 #define Rep(i,a,b) for(int i=(a);i>=(b);i--) 14 const int N=3e5+7,p=950009857,gg=7,gi=135715694; 15 typedef long long LL; 16 typedef double db; 17 using namespace std; 18 int n,m; 19 LL g[N]; 20 21 template<typename T> void read(T &x) { 22 char ch=getchar(); x=0; T f=1; 23 while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar(); 24 if(ch=='-') f=-1,ch=getchar(); 25 for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f; 26 } 27 28 LL ksm(LL a,LL b) { 29 LL rs=1,bs=a%p; 30 while(b) { 31 if(b&1) rs=rs*bs%p; 32 bs=bs*bs%p; 33 b>>=1; 34 } 35 return rs; 36 } 37 38 LL mo(LL x) { return x>=p?x-p:x; } 39 40 void FFT(LL a[],int n,int l,int f) { 41 static int r[N]; 42 For(i,0,n-1) r[i]=(r[i>>1]>>1)|((i&1)<<l-1); 43 For(i,0,n-1) if(i<r[i]) swap(a[i],a[r[i]]); 44 for(int i=1;i<n;i<<=1) { 45 LL wn=ksm((f==1?gg:gi),(p-1)/(i<<1)); 46 for(int j=0,pp=(i<<1);j<n;j+=pp) { 47 LL w=1; 48 for(int k=0;k<i;k++,w=w*wn%p) { 49 LL x=a[j+k],y=w*a[j+k+i]%p; 50 a[j+k]=mo(x+y); a[j+k+i]=(x-y+p)%p; 51 } 52 } 53 } 54 if(f==-1) { 55 LL invv=ksm(n,p-2); 56 For(i,0,n-1) a[i]=a[i]*invv%p; 57 } 58 } 59 60 LL g_inv[N],tp[N]; 61 void get_inv(LL a[],LL b[],int n,int l) { 62 if(n==1) { 63 b[0]=ksm(a[0],p-2); 64 return; 65 } 66 get_inv(a,b,n>>1,l-1); 67 For(i,0,n-1) tp[i]=a[i],tp[i+n]=0; 68 FFT(tp,n<<1,l+1,1); 69 FFT(b,n<<1,l+1,1); 70 For(i,0,n<<1) tp[i]=(2LL-b[i]*tp[i]%p+p)%p*b[i]%p; 71 FFT(tp,n<<1,l+1,-1); 72 For(i,0,n-1) b[i]=tp[i],b[i+n]=0; 73 } 74 75 LL g_ln[N],inv[N]; 76 void get_ln(LL a[],LL b[],int n,int l) { 77 static LL a_dao[N],a_inv[N]; 78 For(i,0,n<<1) a_dao[i]=a_inv[i]=0; 79 For(i,1,n-1) a_dao[i-1]=a[i]*i%p; a_dao[n-1]=0; 80 get_inv(a,a_inv,n,l); 81 FFT(a_dao,n<<1,l+1,1); 82 FFT(a_inv,n<<1,l+1,1); 83 For(i,0,n<<1) a_dao[i]=a_dao[i]*a_inv[i]%p; 84 FFT(a_dao,n<<1,l+1,-1); 85 For(i,0,n-1) b[i]=a_dao[i],b[i+n]=0; 86 Rep(i,n-1,0) b[i]=b[i-1]*inv[i]%p; b[0]=0; 87 } 88 89 void get_exp(LL a[],LL b[],int n,int l) { 90 if(n==1) { 91 b[0]=1; return; 92 } 93 get_exp(a,b,n>>1,l-1); 94 static LL b_ln[N]; 95 For(i,0,n<<1) b_ln[i]=0; 96 get_ln(b,b_ln,n,l); 97 For(i,0,n-1) b_ln[i]=((LL)(i==0)-b_ln[i]+a[i]+p)%p; 98 FFT(b,n<<1,l+1,1); 99 FFT(b_ln,n<<1,l+1,1); 100 For(i,0,n<<1) b_ln[i]=b_ln[i]*b[i]%p; 101 FFT(b_ln,n<<1,l+1,-1); 102 For(i,0,n-1) b[i]=b_ln[i],b[i+n]=0; 103 } 104 105 LL g_k[N]; 106 void get_power(LL a[],LL b[],int n,int l,LL k) { 107 static LL t[N]; 108 For(i,0,n<<1) t[i]=0; 109 get_ln(a,t,n,l); 110 For(i,0,n-1) t[i]=t[i]*k%p; 111 get_exp(t,b,n,l); 112 } 113 114 //#define DEBUG 115 int main() { 116 #ifdef DEBUG 117 freopen("1.in","r",stdin); 118 //freopen(".out","w",stdout); 119 #endif 120 read(n); read(m); 121 g[0]=1; 122 For(i,1,m) { int x; read(x); g[x-1]=mo(g[x-1]+p-1); } 123 int nn=1,ll=0; 124 for(nn=1;nn<=n;nn<<=1) ll++; 125 inv[0]=inv[1]=1; 126 For(i,2,nn) inv[i]=(p-p/i*inv[p%i]%p)%p; 127 get_inv(g,g_inv,nn,ll); 128 get_power(g_inv,g_k,nn,ll,n); 129 printf("%lld ",g_k[n-1]*inv[n]%p); 130 return 0; 131 }
最近感觉很不对劲
不应该是这样的
不应该是现在这个样子
各方面都是
为什么是这样啊
是哪里不对劲吧
到底是哪个地方出了问题呀
可能这周心都已经不在机房了
或者说省选以来都是这样
不管怎么说
终于要回家了
回家之后或许会有什么变化吧
不能这样下去
bad end的flag已经高高立起了
一定要改变一点什么才行呀