luogu P4091 [HEOI2016/TJOI2016]求和

传送门

这一类题都要考虑推式子

首先,原式为\[f(n)=\sum_{i=0}^{n}\sum_{j=0}^{i}S(i,j)*2^j*j!\]

可以看成\[f(n)=\sum_{j=0}^{n}2^j*j!\sum_{i=j}^{n}S(i,j)\]

又因为\[S(i,j)=\frac{1}{j!}\sum_{k=0}^{j}(-1)^k*\binom{j}{k}*(j-k)^i\]

所以\[f(n)=\sum_{j=0}^{n}2^j*j!\sum_{i=0}^{n}\frac{1}{j!}\sum_{k=0}^{j}(-1)^k*\binom{j}{k}*(j-k)^i\]\[f(n)=\sum_{j=0}^{n}2^j*j!\sum_{i=0}^{n}\frac{1}{j!}\sum_{k=0}^{j}(-1)^k*\frac{j!}{k!(j-k)!}*(j-k)^i\]\[f(n)=\sum_{j=0}^{n}2^j*j!\sum_{i=0}^{n}\sum_{k=0}^{j}(-1)^k*\frac{1}{k!(j-k)!}*(j-k)^i\]\[f(n)=\sum_{j=0}^{n}2^j*j!\sum_{k=0}^{j}\frac{(-1)^k}{k!}*\frac{\sum_{i=0}^{n}(j-k)^i}{(j-k)!}\]

后面一个\(\sum\)是卷积形式,可以\(NTT\)求解,(其中\(\frac{\sum_{i=0}^{n}j^i}{j!}=\frac{j^{n+1}-1}{(j-1)j!}\))

#include<bits/stdc++.h>
#define LL long long
#define db double
#define il inline
#define re register

using namespace std;
const int N=100000+10,M=270000+10,mod=998244353,g=3;
il int rd()
{
  int x=0,w=1;char ch=0;
  while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
  while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
  return x*w;
}
int n,m,nn,l,a[M],b[M],rdr[M];
il int fpow(int a,int b)
{
  int an=1;
  while(b){if(b&1) an=1ll*an*a%mod;a=1ll*a*a%mod,b>>=1;}  return an;
}
il void ntt(int *a,int op)
{
  int W,w,x,y;
  for(int i=0;i<nn;++i) if(i<rdr[i]) swap(a[i],a[rdr[i]]);
  for(int i=1;i<nn;i<<=1)
    {
      W=fpow(g,(mod-1)/(i<<1));
      if(op==-1) W=fpow(W,mod-2);
      for(int j=0;j<nn;j+=i<<1)
        {
          w=1;
          for(int k=0;k<i;++k,w=1ll*w*W%mod)
            {
              x=a[j+k],y=1ll*w*a[j+k+i]%mod;
              a[j+k]=(x+y)%mod,a[j+k+i]=(x-y+mod)%mod;
            }
        }
    }
}
int fac[N],iac[N],inv[N];

int main()
{
  n=rd();
  fac[0]=1;
  for(int i=1;i<=n;++i) fac[i]=1ll*fac[i-1]*i%mod;
  iac[n]=fpow(fac[n],mod-2);
  for(int i=n;i>=1;--i) iac[i-1]=1ll*iac[i]*i%mod;
  for(int i=1;i<=n;++i) inv[i]=1ll*iac[i]*fac[i-1]%mod;
  for(int i=0,j=1;i<=n;++i,j=-j) a[i]=(1ll*j*iac[i]%mod+mod)%mod;
  for(int i=0;i<=n;++i) b[i]=1ll*(fpow(i,n+1)-1)*iac[i]%mod*inv[i-1]%mod;
  b[0]=1,b[1]=n+1;
  m=n+n;
  for(nn=1;nn<=m;nn<<=1) ++l;
  for(int i=0;i<nn;++i) rdr[i]=(rdr[i>>1]>>1)|((i&1)<<(l-1));
  ntt(a,1),ntt(b,1);
  for(int i=0;i<nn;++i) a[i]=1ll*a[i]*b[i]%mod;
  ntt(a,-1);
  int invnn=fpow(nn,mod-2),ans=0;
  for(int i=0,j=1;i<=n;++i,j=(j<<1)%mod)
    ans=(ans+1ll*j*fac[i]%mod*a[i]%mod*invnn%mod)%mod;
  printf("%d\n",ans);
  return 0;
}

原文地址:https://www.cnblogs.com/smyjr/p/10080952.html

时间: 2024-10-29 14:00:47

luogu P4091 [HEOI2016/TJOI2016]求和的相关文章

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!

P4091 [HEOI2016/TJOI2016]求和

留待警戒 FFT的时候长度要写的和函数里一样啊XD 瞎扯 这是个第二类斯特林数的理性愉悦颓柿子题目 颓柿子真的是让我hi到不行啦(才没有) 前置芝士 一个公式 \[ \sum_{i=0}^n t^i = \frac{t^{n+1}-1}{t-1} \] 第二类斯特林数 第二类斯特林数的是指把n个对象放到m个集合里面的方案数 其递推式是 \[ S_{n}^{m}=S_{n-1}^{m-1}+mS_{n-1}^{m} \] 容斥原理的得到的通式 \[ S_n^m=\frac{1}{m!}\sum_{

luogu P2825 [HEOI2016/TJOI2016]游戏

题面 https://www.luogu.org/problemnew/show/P2825 题解 水题 二分图匹配的经典模型. 对于硬石头,拆点. // luogu-judger-enable-o2 #include<cstdio> #include<iostream> #include<cstring> #include<vector> #include<queue> #define ri register int #define N 505

Luogu P2824 [HEOI2016/TJOI2016]排序

Link 先二分答案,这样所有的数字就都变成了\(0,1\). 那么区间排序就相当于区间求和再区间覆盖了. #include<bits/stdc++.h> using namespace std; #define N 100007 int read(){int x=0,c=getchar();while(!isdigit(c))c=getchar();while(isdigit(c))x=x*10+c-48,c=getchar();return x;} int a[N],sum[N<&l

[题解] LuoguP4091 [HEOI2016/TJOI2016]求和

传送门 首先我们来看一下怎么求\(S(m,n)\). 注意到第二类斯特林数的组合意义就是将\(m\)个不同的物品放到\(n\)个没有区别的盒子里,不允许有空盒子的方案数. 那么将\(m\)个不同的物品随便扔到\(n\)个盒子里的方案数就是\(n^m\),这里盒子也有区别了. 那么枚举有多少盒子有物品,然后斯特林数安排一下,注意到这是的盒子是没有区别的,再排列就好了,即 \[ n^m=\sum\limits_{i=0}^n \binom{n}{i}S(m,i)i! \] 但我们要求的是\(S\),

[HEOI2016/TJOI2016]求和

Discription 在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

[HEOI2016/TJOI2016]求和——第二类斯特林数

给你斯特林数就换成通项公式,给你k次方就换成斯特林数 考虑换成通项公式之后,组合数没有什么好的处理方法 直接拆开,消一消阶乘 然后就发现了(j-k)和k! 往NTT方向靠拢 然后大功告成 其实只要想到把斯特林公式换成通项公式,考虑用NTT优化掉(j-k)^i 后面都是套路了. #include<bits/stdc++.h> #define reg register int #define il inline #define numb (ch^'0') #define int long long

[HEOI2016/TJOI2016]求和 斯特林数 + NTT

Description 计算函数的值 \[f(n) = \sum \limits_{i=0}^{n} \sum \limits_{j=0}^{i} 2^j \times j! \times S(i,j)\] Solution 大家好,我是练习推柿子半天的个人练习生\(newbielyx\). \[ f(n) = \sum \limits_{i=0}^{n} \sum \limits_{j=0}^{i} 2^j \times j! \times S(i,j) \] \[ = \sum \limit

[Luogu 2261] CQOI2007 余数求和

[Luogu 2261] CQOI2007 余数求和 <题目链接> 这一定是我迄今为止见过最短小精悍的省选题了,核心代码 \(4\) 行,总代码 \(12\) 行,堪比小凯的疑惑啊. 这题一看暴力很好打,然而 \(10^{9}\) 的范围注定会卡掉暴力. 所以我们要用除法分块来优化. 由题意得:\(ans = \sum_{i=1}^{n} k \bmod i\) 我们知道,\(a \bmod b = a - b \times \lfloor \frac{a}{b} \rfloor\) 因此,\