不错的推柿子题

LOJ #2058

题意:求$\sum\limits_{i=0}^n\sum\limits_{j=0}^nS(i,j)·2^j·j!$其中$ S(n,m)$是第二类斯特林数


$ Solution:$

首先考虑第二类斯特林数的意义:将$ n$个有标号元素放入$ m$个无标号集合(无空集)的方案数

我们枚举空集的数量容斥:$ S(n,m)=\frac{1}{m!}\sum\limits_{k=0}^m(-1)^kC_m^k(m-k)^n$

乘上$ \frac{1}{m!}$是因为容斥的集合带标号而斯特林数本身不带标号

这样可以将原式展开得:

$ \sum\limits_{i=0}^n \sum\limits_{j=0}^n2^j \sum\limits_{k=0}^j(-1)^kC_j^k(j-k)^i$     (消阶乘项)

把组合数展开得$ \sum\limits_{i=0}^n \sum\limits_{j=0}^n 2^j j! \sum\limits_{k=0}^j \frac{(-1)^k}{k!} \frac{(j-k)^i}{(j-k)!}$

改变枚举顺序得$ \sum\limits_{j=0}^n 2^j j! \sum\limits_{k=0}^j \frac{(-1)^k}{k!} \frac{ \sum\limits_{i=0}^n (j-k)^i}{(j-k)!}$

令$ A(x)= \frac{(-1)^x}{x!}$,$ B(x)=\frac{ \sum\limits_{i=0}^n x^i}{x!}$

则原式为$ \sum\limits_{j=0}^n 2^j j! \sum\limits_{k=0}^jA(k)B(j-k)$

容易发现这是一个卷积形式,而函数$ A,B$均可以在$ O(n)$时间复杂度内完成

这样可以直接用$ NTT$优化,时间复杂度:$ O(n \ log \  n)$


$ my \ code:$

#include<ctime>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
#define p 998244353
#define rt register int
#define ll long long
using namespace std;
inline ll read(){
ll x = ; char zf = ; char ch = getchar();
while (ch != '-' && !isdigit(ch)) ch = getchar();
if (ch == '-') zf = -, ch = getchar();
while (isdigit(ch)) x = x * + ch - '', ch = getchar(); return x * zf;
}
void write(ll y){if(y<)putchar('-'),y=-y;if(y>)write(y/);putchar(y%+);}
void writeln(const ll y){write(y);putchar('\n');}
int i,j,k,m,n,x,y,z,cnt;
int inv[],jc[],njc[];
int ksm(int x,int y){
int ans=;
for(rt i=y;i;i>>=,x=1ll*x*x%p)if(i&)ans=1ll*ans*x%p;
return ans;
}
vector<int>A,B,f,R;int lim=;
int calc(int x,int L,int R){
if(x==)return R-L+;
return 1ll*(ksm(x,R+)-ksm(x,L))*ksm(x-,p-)%p;
}
void init(int n){
for(rt i=;i<=;i++)inv[i]=jc[i]=njc[i]=;
for(rt i=;i<=n;i++){
jc[i]=1ll*jc[i-]*i%p;
inv[i]=1ll*inv[p%i]*(p-p/i)%p;
njc[i]=1ll*njc[i-]*inv[i]%p;
}
while(lim<=n+n)lim<<=;
A.resize(lim);B.resize(lim);f.resize(lim);
A[]=;for(rt i=,tag=-;i<=n;i++,tag*=-)A[i]=tag*njc[i];
B[]=;for(rt i=;i<=n;i++)B[i]=1ll*njc[i]*calc(i,,n)%p;
}
namespace poly{
void getR(int n){
R.resize(n);
for(rt i=;i<n;i++)R[i]=(R[i>>]>>)|(i&)*(n>>);
}
void NTT(int n,vector<int>&A,int fla){
for(rt i=;i<n;i++)if(i>R[i])swap(A[i],A[R[i]]);
for(rt i=;i<n;i<<=){
int w=ksm(,(p-)//i);
for(rt j=;j<n;j+=i<<){
int K=;
for(rt k=;k<i;k++,K=1ll*K*w%p){
int x=A[j+k],y=1ll*K*A[i+j+k]%p;
A[j+k]=(x+y)%p,A[i+j+k]=(x-y)%p;
}
}
}
if(fla==-){
reverse(A.begin()+,A.end());int invn=ksm(n,p-);
for(rt i=;i<n;i++)A[i]=1ll*A[i]*invn%p;
}
}
}
using namespace poly;
int main(){
n=read();init(n);
int ans=;getR(lim);
NTT(lim,A,);NTT(lim,B,);
for(rt i=;i<lim;i++)f[i]=1ll*A[i]*B[i]%p;
NTT(lim,f,-);
for(rt i=;i<=n;i++)(ans+=1ll*ksm(,i)*jc[i]%p*f[i]%p)%=p;
cout<<(ans+p)%p;
return ;
}

LOJ #2058「TJOI / HEOI2016」求和的更多相关文章

  1. loj2058 「TJOI / HEOI2016」求和 NTT

    loj2058 「TJOI / HEOI2016」求和 NTT 链接 loj 思路 \[S(i,j)=\frac{1}{j!}\sum\limits_{k=0}^{j}(-1)^{k}C_{j}^{k ...

  2. loj#2054. 「TJOI / HEOI2016」树

    题目链接 loj#2054. 「TJOI / HEOI2016」树 题解 每次标记覆盖整棵字数,子树维护对于标记深度取max dfs序+线段树维护一下 代码 #include<cstdio> ...

  3. loj #2055. 「TJOI / HEOI2016」排序

    #2055. 「TJOI / HEOI2016」排序   题目描述 在 2016 年,佳媛姐姐喜欢上了数字序列.因而他经常研究关于序列的一些奇奇怪怪的问题,现在他在研究一个难题,需要你来帮助他. 这个 ...

  4. 「TJOI / HEOI2016」求和 的一个优秀线性做法

    我们把\(S(i, j)j!\)看成是把\(i\)个球每次选择一些球(不能为空)扔掉,选\(j\)次后把所有球都扔掉的情况数(顺序有关).因此\(S(i, j)j! = i![x^i](e^x - 1 ...

  5. loj#2059. 「TJOI / HEOI2016」字符串 sam+线段树合并+倍增

    题意:给你一个子串,m次询问,每次给你abcd,问你子串sa-b的所有子串和子串sc-d的最长公共前缀是多长 题解:首先要求两个子串的最长公共前缀就是把反过来插入变成最长公共后缀,两个节点在paren ...

  6. loj2058 「TJOI / HEOI2016」求和

    推柿子 第二类斯特林数的容斥表达 fft卡精度就用ntt吧qwq. #include <iostream> #include <cstdio> using namespace ...

  7. AC日记——#2057. 「TJOI / HEOI2016」游戏 LOJ

    #2057. 「TJOI / HEOI2016」游戏 思路: 最大流: 代码: #include <cstdio> #include <cstring> #include &l ...

  8. 「TJOI / HEOI2016」字符串

    「TJOI / HEOI2016」字符串 题目描述 佳媛姐姐过生日的时候,她的小伙伴从某东上买了一个生日礼物.生日礼物放在一个神奇的箱子中.箱子外边写了一个长为 \(n\) 的字符串 \(s\),和 ...

  9. AC日记——#2054. 「TJOI / HEOI2016」树

    #2054. 「TJOI / HEOI2016」树 思路: 线段树: 代码: #include <cstdio> #include <cstring> #include < ...

随机推荐

  1. ANIS与UNICODE字符格式转换:MultiByteToWideChar() 和WideCharToMultiByte() 函数

    资料来自: http://blog.csdn.net/holamirai/article/details/47948745 http://www.cnblogs.com/wanghao111/arch ...

  2. linux系统调用之网络管理2

    socketcall socket系统调用 socket 建立socket bind 绑定socket到端口 connect 连接远程主机 accept 响应socket连接请求 send 通过soc ...

  3. Can not issue data manipulation statements with executeQuery()错误解决

    转: Can not issue data manipulation statements with executeQuery()错误解决 2012年03月27日 15:47:52 katalya 阅 ...

  4. C语言进阶——Day 1

    C语言提高笔记 Day 1 小数据赋给大变量,首位是1则在前面自动补充1,首位是0则在前方自动补充0. 大数据赋给小变量,低位字节对齐,truncate截断,有可能会造成数据丢失. 程序和进程的差别: ...

  5. 字符输出流 FileWriter

    FileWriter 方法: writer(); flush(); package cn.lideng.demo3; import java.io.FileWriter; import java.io ...

  6. flask 渲染jinja2模版和传参

    渲染模版(html文件) A.模版文件(html)放入到template目录下,项目启动的时候会从template目录里查找, B.从flask中导入“render_tempalte”函数 C.在视图 ...

  7. MyBatis-${}与#{}

    一.看两种取值的效果 <select id="selectMyUserIdAndAge" resultType="myUser"> select * ...

  8. Memcache在.Net中的使用

    一.Memcache基本概念(socket服务器) 本质:是一个在内存上存储的hash表,key的最大值是255字符,最长过期时间为30天 特点:惰性删除,没有监控数据过期的机制,实现最基本的key- ...

  9. inux进程/线程调度策略与 进程优先级

    目的: 系统性的认识linux的调度策略(SCHED_OTHER.SCHED_FIFO.SCHED_RR): 实时调度?分时调度? 混搭系统(实时任务+分时任务),怎样调度. linux的调度策略 l ...

  10. [leetcode-128] 最长连续序列

    给定一个未排序的整数数组,找出最长连续序列的长度. 要求算法的时间复杂度为 O(n). 示例: 输入: [100, 4, 200, 1, 3, 2] 输出: 4 解释: 最长连续序列是 [1, 2, ...