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

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

#include <cstdio>
#include <cstring>
#include <algorithm>
const int N=400010;
const int P=998244353;
typedef long long LL;
inline int Pow(int x,int y){
  int ret=1;
  while(y){
    if(y&1)ret=(LL)ret*x%P;
    x=(LL)x*x%P,y>>=1;
  }return ret;
}
int A[N],B[N],rev[N],len;
int ai[N],bi[N],ci[N];
int jie[N],ni[N],inv[N],n;
inline void ntt(int *C,int opt){
  register int i,j,k,w;int wn,temp;
  for(i=1;i<len;++i)if(i<rev[i])std::swap(C[i],C[rev[i]]);
  for(k=2;k<=len;k<<=1){
    wn=Pow(3,(P-1)/k);
    if(opt==-1)wn=Pow(wn,P-2);
    for(i=0;i<len;i+=k){
      w=1;
      for(j=0;j<(k>>1);++j,w=(LL)w*wn%P){
        temp=(LL)w*C[i+j+(k>>1)]%P;
        C[i+j+(k>>1)]=(C[i+j]-temp+P)%P;
        C[i+j]=(C[i+j]+temp)%P;
      }
    }
  }
}
inline void mul(int *a,int *b,int *c,int n){
  len=1;while(len<n)len<<=1;int i;
  for(i=1;i<len;++i)rev[i]=(rev[i>>1]>>1)|((i&1)?(len>>1):0);
  for(i=0;i<len;++i)A[i]=a[i],B[i]=b[i];
  ntt(A,1),ntt(B,1);
  for(i=0;i<len;++i)A[i]=(LL)A[i]*B[i]%P;
  ntt(A,-1);
  int Inv=Pow(len,P-2);
  for(i=0;i<len;++i)c[i]=(LL)A[i]*Inv%P;
}
int main(){
  scanf("%d",&n);int i,ans=1,temp=1;
  jie[0]=ni[0]=1,inv[1]=1;
  for(i=2;i<=n;++i)inv[i]=((-(LL)(P/i)*inv[P%i])%P+P)%P;
  for(i=1;i<=n;++i)jie[i]=(LL)jie[i-1]*i%P,ni[i]=(LL)ni[i-1]*inv[i]%P;
  bi[0]=0,bi[1]=n,ai[0]=1,ai[1]=P-1;
  for(i=2;i<=n;++i)
    bi[i]=(LL)i*(Pow(i,n)-1+P)%P*ni[i]%P*inv[i-1]%P,ai[i]=(i&1)?(P-ni[i]):ni[i];
  mul(ai,bi,ci,n+n+2);
  for(i=1;i<=n;++i)
    temp=(((LL)temp)<<1LL)%P,ans=(ans+(LL)ci[i]*temp%P*jie[i])%P;
  printf("%d\n",ans);
  return 0;
}

原文地址:https://www.cnblogs.com/TSHugh/p/8480847.html

时间: 2024-10-07 18:33:04

【BZOJ 4555】[Tjoi2016&Heoi2016]求和 NTT+第二类斯特林数的相关文章

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

[Tjoi2016&Heoi2016]求和 Time Limit: 40 Sec  Memory Limit: 128 MBSubmit: 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 &l

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

【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

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】4555: [Tjoi2016&amp;Heoi2016]求和 排列组合+多项式求逆 或 斯特林数+NTT

[题意]给定n,求Σi=0~nΣj=1~i s(i,j)*2^j*j!,n<=10^5. [算法]生成函数+排列组合+多项式求逆 [题解]参考: [BZOJ4555][Tjoi2016&Heoi2016]求和-NTT-多项式求逆 $ans=\sum_{i=0}^{n}\sum_{j=0}^{i}s(i,j)*2^j*j!$ 令$g(n)=\sum_{j=0}^{n}s(n,j)*2^j*j!$ 则ans是Σg(i),只要计算出g(i)的生成函数就可以统计答案. g(n)可以理解为将n个数划分

【BZOJ4555】[Tjoi2016&amp;Heoi2016]求和 NTT

[BZOJ4555][Tjoi2016&Heoi2016]求和 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 输入