Bzoj4555 [Tjoi2016&Heoi2016]求和

Time Limit: 40 Sec  Memory Limit: 128 MB
Submit: 327  Solved: 262

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

数学问题 斯特林数 分治NTT

窝……窝既不会推公式也不会分治NTT,于是可耻地抄了代码

http://www.cnblogs.com/candy99/p/6648765.html

  1 /*by SilverN*/
  2 #include<iostream>
  3 #include<algorithm>
  4 #include<cstring>
  5 #include<cstdio>
  6 #include<cmath>
  7 #include<vector>
  8 #define LL long long
  9 using namespace std;
 10 const int mod=998244353;
 11 const int mxn=400010;
 12 int read(){
 13     int x=0,f=1;char ch=getchar();
 14     while(ch<‘0‘ || ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
 15     while(ch>=‘0‘ && ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}
 16     return x*f;
 17 }
 18 LL inv[mxn],fac[mxn],invF[mxn];
 19 void init(int n){
 20     inv[1]=1;fac[0]=fac[1]=1;
 21     invF[1]=invF[0]=1;
 22     for(int i=2;i<=n;i++){
 23         inv[i]=((-mod/i)*inv[mod%i]%mod+mod)%mod;
 24         fac[i]=fac[i-1]*i%mod;
 25         invF[i]=invF[i-1]*inv[i]%mod;
 26     }
 27     return;
 28 }
 29 LL ksm(LL a,LL k){
 30     LL res=1;
 31     while(k){
 32         if(k&1)res=(res*a)%mod;
 33         a=(a*a)%mod;
 34         k>>=1;
 35     }
 36     return res;
 37 }
 38 LL f[mxn];
 39 int N,len;
 40 LL a[mxn],b[mxn];
 41 int rev[mxn];
 42
 43 void NTT(LL *a,int flag){
 44     for(int i=0;i<N;i++)
 45         if(i<rev[i])swap(a[i],a[rev[i]]);
 46     for(int i=1;i<N;i<<=1){
 47         int p=i<<1;
 48         LL gn=ksm(3,(flag==1)?(mod-1)/p:mod-1-(mod-1)/p);
 49         for(int j=0;j<N;j+=p){
 50             LL g=1;
 51             for(int k=0;k<i;k++,g=(LL)g*gn%mod){
 52                 LL x=a[j+k],y=(LL)g*a[j+k+i]%mod;
 53                 a[j+k]=(x+y)%mod;
 54                 a[j+k+i]=(x-y+mod)%mod;
 55             }
 56         }
 57     }
 58     if(flag==-1){
 59         LL Inv=ksm(N,mod-2);
 60         for(int i=0;i<N;i++)a[i]=a[i]*Inv%mod;
 61     }
 62     return;
 63 }
 64 void solve(int l,int r){
 65     if(l==r)return;
 66     int mid=(l+r)>>1;
 67     solve(l,mid);
 68     int m=r-l+1;
 69     len=0;
 70     for(N=1;N<m;N<<=1)len++;
 71     for(int i=0;i<N;i++)
 72         rev[i]=(rev[i>>1]>>1)|((i&1)<<(len-1));
 73     for(int i=0;i<N;i++)a[i]=b[i]=0;
 74     for(int i=l;i<=mid;i++){
 75         a[i-l]=f[i];
 76 //        printf("i:%d f:%lld\n",i,f[i]);
 77     }
 78     for(int i=0;i<=r-l;i++)
 79         b[i]=invF[i];
 80     NTT(a,1);NTT(b,1);
 81     for(int i=0;i<N;i++)a[i]=a[i]*b[i]%mod;
 82     NTT(a,-1);
 83     for(int i=mid+1;i<=r;i++)
 84         f[i]=(f[i]+2*a[i-l])%mod;//累加贡献
 85 //    printf("mid:%d f:%lld\n",mid,f[mid+1]);
 86     solve(mid+1,r);
 87     return;
 88 }
 89 int n;
 90 int main(){
 91     int i,j;
 92     n=read();
 93     init(n+1);
 94     f[0]=1;
 95     solve(0,n);
 96     LL ans=0;
 97     for(int i=0;i<=n;i++){
 98 //        printf("i:%d f:%lld\n",i,f[i]);
 99         ans=(ans+f[i]*fac[i]%mod)%mod;
100     }
101     printf("%lld\n",ans);
102     return 0;
103 }
时间: 2024-12-21 21:51:23

Bzoj4555 [Tjoi2016&Heoi2016]求和的相关文章

[BZOJ4555][TJOI2016&amp;HEOI2016]求和(分治FFT)

解法一:容易得到递推式,可以用CDQ分治+FFT 代码用时:1h 比较顺利,没有低级错误. 实现比较简单,11348ms #include<cstdio> #include<algorithm> #define rep(i,l,r) for (int i=l; i<=r; i++) typedef long long ll; using namespace std; const int N=(1<<18)+100,P=998244353,g=3; int n,re

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】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 输入

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

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

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

4555: [Tjoi2016&amp;Heoi2016]求和

我们省选的题- 考虑这个式子的组合意义,对于每一个i,枚举j表示将i个小球放入j个有序集合,且每个集合选择或者不选的方案数. 我们用f[i]表示将i个小球放入任意个有序集合,且每个集合选择或不选的方案数,则枚举最后一个集合的大小i-j,可以得到递推式: for(int i = 1;i <=n ;i ++) for(int j = 0;j < i ;j ++)f[i]=(f[i]+f[j]*c[i][j]*2); c[i][j]是组合数. 意义就是有j个小球任意组合,剩下的组成最后一个集合,且这

[Tjoi2016&amp;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 输入只有一个正整数 Output 输出f(n).由于结果会很大,输出f(n)

BZOJ 4553 Tjoi2016&amp;Heoi2016 序列

Tjoi2016&Heoi2016序列 Description 佳媛姐姐过生日的时候,她的小伙伴从某宝上买了一个有趣的玩具送给他.玩具上有一个数列,数列中某些项的值 可能会变化,但同一个时刻最多只有一个值发生变化.现在佳媛姐姐已经研究出了所有变化的可能性,她想请教你 ,能否选出一个子序列,使得在任意一种变化中,这个子序列都是不降的?请你告诉她这个子序列的最长长度即可 .注意:每种变化最多只有一个值发生变化.在样例输入1中,所有的变化是: 1 2 3 2 2 3 1 3 3 1 1 31 2 4