bzoj 4555 [Tjoi2016&Heoi2016]求和 NTT 第二类斯特林数 等比数列求和优化

[Tjoi2016&Heoi2016]求和

Time Limit: 40 Sec  Memory Limit: 128 MB
Submit: 679  Solved: 534
[Submit][Status][Discuss]

Description

在2016年,佳媛姐姐刚刚学习了第二类斯特林数,非常开心。

现在他想计算这样一个函数的值:

S(i, j)表示第二类斯特林数,递推公式为:

S(i, j) = j ∗ S(i − 1, j) + S(i − 1, j − 1), 1 <= j <= i − 1。

边界条件为:S(i, i) = 1(0 <= i), S(i, 0) = 0(1 <= i)

你能帮帮他吗?

Input

输入只有一个正整数

Output

输出f(n)。由于结果会很大,输出f(n)对998244353(7 × 17 × 223 + 1)取模的结果即可。1 ≤ n ≤ 100000

Sample Input

3

Sample Output

87

HINT

Source

多谢大佬的blog,我自己写比较慢,所以直接贴了。

这题本来是来练多项式求逆的,但是好像其它方法也可以做。

然后就通过这样的方法解出了,我们都知道等比数列求和的第一项需要特殊考虑,所以g[1]=n

然后就是卷积的形式了,从n^2 log n----------->  n log n

 1 #include<cstring>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<iostream>
 5 #include<algorithm>
 6
 7 #define ll long long
 8 #define mod 998244353
 9 #define G 3
10 #define N 100007
11 using namespace std;
12 inline int read()
13 {
14     int x=0,f=1;char ch=getchar();
15     while(!isdigit(ch)){if(ch==‘-‘)f=-1;ch=getchar();}
16     while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-‘0‘;ch=getchar();}
17     return x*f;
18 }
19
20 int n,num,L,inv;
21 int jc[N],ny[N],jcn[N];
22 ll a[N<<2],b[N<<2],rev[N<<2];
23
24 int fast_pow(int a,int b)
25 {
26     int ans=1;
27     while(b)
28     {
29         if (b&1) ans=(ll)ans*a%mod;
30         a=(ll)a*a%mod;
31         b>>=1;
32     }
33     return ans;
34 }
35 void NTT(ll *a,ll f)
36 {
37     for (ll i=0;i<num;i++)
38         if (i<rev[i]) swap(a[i],a[rev[i]]);
39     for (ll i=1;i<num;i<<=1)
40     {
41         ll wn=fast_pow(G,(mod-1)/(i<<1));
42         for (ll j=0;j<num;j+=(i<<1))
43         {
44             ll w=1;
45             for (ll k=0;k<i;w=(ll)w*wn%mod,k++)
46             {
47                 ll x=a[j+k],y=(ll)w*a[j+k+i]%mod;
48                 a[j+k]=(x+y>=mod)?x+y-mod:x+y,a[j+k+i]=(x-y<0)?x-y+mod:x-y;
49             }
50         }
51     }
52     if (f==-1)
53     {
54         for (ll i=1;i<num/2;i++) swap(a[i],a[num-i]);
55         for (ll i=0;i<num;i++) a[i]=(ll)a[i]*inv%mod;
56     }
57 }
58 int main()
59 {
60     n=read();
61     jc[0]=1,ny[0]=1,jcn[0]=1;
62     for (int i=1;i<=n;i++)
63         jc[i]=(ll)jc[i-1]*i%mod,ny[i]=fast_pow(i,mod-2),jcn[i]=(ll)jcn[i-1]*ny[i]%mod;
64     for (int i=0;i<=n;i++)
65         a[i]=(ll)((i&1)?-1:1)*jcn[i];
66     for (int i=2;i<=n;i++)
67         b[i]=(ll)(fast_pow(i,n+1)-i)*jcn[i]%mod*ny[i-1]%mod;b[1]=n;
68     for (num=1;num<=2*n;num<<=1,L++);if (L) L--;inv=fast_pow(num,mod-2);
69     for (int i=0;i<=num;i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<L);
70     NTT(a,1),NTT(b,1);
71     for (int i=0;i<num;i++)
72         a[i]=(ll)a[i]*b[i]%mod;
73     NTT(a,-1);
74     int ans=1;//第一项的等比数列的影响
75     for (int i=1;i<=n;i++)
76         (ans+=(ll)fast_pow(2,i)*jc[i]%mod*a[i]%mod)%=mod;
77     ans=(ans+mod)%mod;
78     printf("%d\n",ans);
79 }

原文地址:https://www.cnblogs.com/fengzhiyuan/p/8659019.html

时间: 2024-10-09 18:39:52

bzoj 4555 [Tjoi2016&Heoi2016]求和 NTT 第二类斯特林数 等比数列求和优化的相关文章

【BZOJ 4555】[Tjoi2016&amp;Heoi2016]求和 NTT+第二类斯特林数

用到第二类斯特林数的性质,做法好像很多,我打的是直接ntt,由第二类斯特林数的容斥公式可以推出,我们可以对于每一个i,来一次ntt求出他与所有j组成的第二类斯特林数的值,这个时候我们是O(n^2logn)的,还不如暴力,但是我们发现,对于刚刚提到的容斥的式子,将其化为卷积形式后,其一边的每一项对于每一个i都相同,另一边的每一项是对于所有的i形成一个n项的等比数列,这样我们可以把成等比数列的一边求和,用固定的一边去卷他们的和,这时候的答案的每一项就是所有的i的这一项的和,然后我们再O(n)乘上阶乘

【BZOJ4555】求和(第二类斯特林数,组合数学,NTT)

[BZOJ4555]求和(第二类斯特林数,组合数学,NTT) 题面 BZOJ 题解 推推柿子 \[\sum_{i=0}^n\sum_{j=0}^iS(i,j)·j!·2^j\] \[=\sum_{i=0}^n\sum_{j=0}^nS(i,j)·j!·2^j\] \[=\sum_{i=0}^n\sum_{j=0}^nj!·2^j(\frac{1}{j!}\sum_{k=0}^j(-1)^k·C_j^k·(j-k)^i)\] \[=\sum_{j=0}^n2^j\sum_{k=0}^j(-1)^k

BZOJ4555 [Tjoi2016&amp;Heoi2016]求和 【第二类斯特林数 + NTT】

题目 在2016年,佳媛姐姐刚刚学习了第二类斯特林数,非常开心. 现在他想计算这样一个函数的值: S(i, j)表示第二类斯特林数,递推公式为: S(i, j) = j ? S(i ? 1, j) + S(i ? 1, j ? 1), 1 <= j <= i ? 1. 边界条件为:S(i, i) = 1(0 <= i), S(i, 0) = 0(1 <= i) 你能帮帮他吗? 输入格式 输入只有一个正整数 输出格式 输出f(n).由于结果会很大,输出f(n)对998244353(7

bzoj 5093 [Lydsy1711月赛]图的价值 NTT+第二类斯特林数

[Lydsy1711月赛]图的价值 Time Limit: 30 Sec  Memory Limit: 256 MBSubmit: 245  Solved: 128[Submit][Status][Discuss] Description “简单无向图”是指无重边.无自环的无向图(不一定连通). 一个带标号的图的价值定义为每个点度数的k次方的和. 给定n和k,请计算所有n个点的带标号的简单无向图的价值之和. 因为答案很大,请对998244353取模输出. Input 第一行包含两个正整数n,k(

【bzoj5093】[Lydsy1711月赛]图的价值(NTT+第二类斯特林数)

题意: 给定\(n\)个点,一个图的价值定义为所有点的度数的\(k\)次方之和. 现在计算所有\(n\)个点的简单无向图的价值之和. 思路: 将式子列出来: \[ \sum_{i=1}^n\sum_{j=0}^{n-1}{n-1\choose j}2^{\frac{(n-1)(n-2)}{2}}j^k \] 表示分别考虑每个点的贡献,我们只需要枚举其度数即可,其余的边任意连. 然后我们将后面的\(j^k\)用第二类斯特林数展开: \[ \begin{aligned} &\sum_{i=1}^{n

P4091 [HEOI2016/TJOI2016]求和(第二类斯特林数,ntt)

题面:https://www.luogu.org/problem/P4091 题解:\[\begin{array}{l}f(n) = \sum\limits_{i = 0}^n {\sum\limits_{j = 0}^i {{\rm{S}}(i,j) \cdot {2^{\rm{j}}} \cdot j!} } \\ = \sum\limits_{i = 0}^n {\sum\limits_{j = 0}^n {{\rm{S}}(i,j) \cdot {2^{\rm{j}}} \cdot j!

bzoj 2159 Crash 的文明世界 —— 第二类斯特林数+树形DP

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2159 使用公式:\( n^{k} = \sum\limits_{i=0}^{k} S(k,i) * i! * C_{n}^{i} \) 所以维护 \( f[x][i] = \sum\limits_{u\in subtree[x],d=dist(x,u)}^{n} C_{d}^{i} \) 然后利用 \( C_{n}^{m} = C_{n-1}^{m} + C_{n-1}^{m-1} \),

bzoj 5093 图的价值 —— 第二类斯特林数+NTT

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=5093 每个点都是等价的,从点的贡献来看,得到式子: \( ans = n * \sum\limits_{d=0}^{n-1} d^{k} * 2^{C_{n-1}^{2}} * C_{n-1}^{d} \) 使用 \( n^{k} = \sum\limits_{i=0}^{k} S(k,i) * i! *C_{n}^{i} \) 得到 \( ans = n * \sum\limits_{d

【BZOJ5093】图的价值(第二类斯特林数,组合数学,NTT)

[BZOJ5093]图的价值(第二类斯特林数,组合数学,NTT) 题面 BZOJ 题解 单独考虑每一个点的贡献: 因为不知道它连了几条边,所以枚举一下 \[\sum_{i=0}^{n-1}C_{n-1}^i·i^k·2^{\frac{n(n-1)}{2}}\] 因为有\(n\)个点,所以还要乘以一个\(n\) 所以,我们真正要求的就是: \[\sum_{i=0}^{n-1}C_{n-1}^i·i^k\] 怎么做? 看到了\(i^k\)想到了第二类斯特林数 \[m^n=\sum_{i=0}^{m}