bzoj 4555 求和
求 $\sum\limits_{i=0}^n\sum\limits_{j=0}^n Stirling2(i,j) \times 2^j \times j!$
$n \leq 100000$
sol:
小清新斯特林数多项式题
首先熟知斯特林数的卷积形式 $Stirling2(i,j) = \sum\limits_{k=0}^j \frac{(-1)^{(j-k)}}{(j-k)!} \times \frac{k^i}{k!}$
这题就是先对 $i$ 求个前缀和,再乘以 $2^j \times j!$ 再求和
于是卷积后一项的 $k^i \rightarrow \sum\limits_{i=0}^n k^i$
这是一个等比数列求和的形式,注意特判一下 $k=1$ 形式即可
然后就是套路啦,令 $A(x) = \frac{\sum\limits_{i=0}^n{k^i}}{k!} x$,$B(x)=\frac{(-1)^i}{i!}$,$C = A \times B$
则 $ans = \sum\limits_{i=0}^n 2^i \times i! \times [x^i]C(x)$
注意 $A(x),B(x),C(x)$ 的常数项都是 $1$
#include <bits/stdc++.h>
#define LL long long
#define rep(i, s, t) for (register int i = (s), i##end = (t); i <= i##end; ++i)
#define dwn(i, s, t) for (register int i = (s), i##end = (t); i >= i##end; --i)
using namespace std;
inline int read() {
int x = ,f = ; char ch = getchar();
for(; !isdigit(ch); ch = getchar())if(ch == '-') f = -f;
for(; isdigit(ch); ch = getchar())x = * x + ch - '';
return x * f;
}
const int maxn = , mod = ;
inline int inc(int x, int y) { x += y; if(x >= mod) x -= mod; return x; }
inline int dec(int x, int y) { x -= y; if(x < ) x += mod; return x; }
inline int mul(int x, int y) { return 1LL * x * y % mod; }
inline int ksm(int x, int t, int res = ) { for(; t; x = mul(x, x), t = t >> ) if(t & ) res = mul(res, x); return res; }
int n, a[maxn], b[maxn];
int r[maxn], lg[maxn], fac[maxn], ifac[maxn], pw[maxn];
void fft(int *a, int n, int f) {
rep(i, , n-) r[i] = (r[i >> ] >> ) | ((i & ) << (lg[n] - ));
rep(i, , n-) if(i < r[i]) swap(a[i], a[r[i]]);
for(register int i = ; i < n; i <<= ) {
int wn = ksm(, (mod - ) / (i << ));
if(f == -) wn = ksm(wn, mod - );
for(register int j = ; j < n; j += (i << )) {
int w = ;
for(register int k = ; k < i; k++, w = mul(w, wn)) {
int x = a[j + k], y = mul(w, a[j + k + i]);
a[j + k] = inc(x, y);
a[j + k + i] = dec(x, y);
}
}
}
if(f == -) {
int inv_n = ksm(n, mod - );
rep(i, , n - ) a[i] = mul(a[i], inv_n);
}
}
inline int cal(int x) {
if(x == ) return n + ;
else return mul(dec(ksm(x, n+), ), ksm(dec(x, ), mod - ));
}
int main() {
lg[] = -; rep(i, , maxn - ) lg[i] = lg[i >> ] + ;
n = read(); int len = ; for(; len <= (n<<); len <<= );
fac[] = ifac[] = ifac[] = pw[] = ; rep(i, , n) fac[i] = mul(fac[i - ], i);
rep(i, , n) ifac[i] = mul((mod - mod / i), ifac[mod % i]);
rep(i, , n) ifac[i] = mul(ifac[i], ifac[i - ]);
//cout << mul(ifac[3], fac[3]) << endl;
rep(i, , n) pw[i] = inc(pw[i - ], pw[i - ]);
a[] = b[] = ; rep(i, , n) a[i] = mul(cal(i), ifac[i]);
rep(i, , n) b[i] = (i & ) ? (mod - ifac[i]) : ifac[i];
fft(a, len, ); fft(b, len, );
//for(int i=0;i<len;i++) cout << a[i] << " "; cout << endl;
// for(int i=0;i<len;i++) cout << b[i] << " "; cout << endl;
rep(i, , len - ) a[i] = mul(a[i], b[i]);
// for(int i=0;i<len;i++) cout << a[i] << " "; cout << endl;
fft(a, len, -); int ans = ;
//for(int i=1;i<=n;i++) cout << a[i] << " "; cout << endl;
rep(i, , n) ans = inc(ans, mul(pw[i], mul(fac[i], a[i])));
cout << inc(ans, ) << endl;
}
还有一个小清新多项式求逆的做法
令 $f(n) = \sum\limits_{i=0}^n Stirling2(n,i) \times i! \times 2^i$,这个东西的组合意义为把 $n$ 个不同的物品放入若干个不同的集合中,且每个集合有两种不同的状态的方案数
枚举最后一个集合的大小和状态,得到 $f(n) = \sum\limits_{i=1}^n 2 \times \binom{n}{i} \times f(n-i)$
多项式求逆即可(远古代码
#include<bits/stdc++.h>
#define LL long long
using namespace std;
const int maxn = ,P = ,G = ;
int n,L,num,R[maxn],a[maxn],b[maxn],c[maxn],d[maxn];
int m;
int INV[maxn];
inline int ksm(int x,int t)
{
int res = ;
while(t)
{
if(t & ) res = 1LL * res * x % P;
x = 1LL * x * x % P;
t >>= ;
}
return res;
}
inline void NTT(int *a,int f,int n,int L)
{
for(int i=;i<n;i++) R[i] = (R[i>>] >> ) | ((i & ) << (L - ));
for(int i=;i<n;i++)if(i < R[i])swap(a[i],a[R[i]]);
for(int i=;i<n;i<<=)
{
int wn = ksm(G,(P - ) / (i << ));
if(f == -)wn = ksm(wn,P - );
for(int j=;j<n;j+=(i<<))
{
int w = ;
for(int k=;k<i;k++,w=1LL * w * wn % P)
{
int x = a[j + k], y = 1LL * w * a[j + k + i ] % P;
a[j + k] = ((x + y) % P + P) % P;
a[j + k + i] = ((x - y) % P + P) % P;
}
}
}
if(f == -)
{
int inv = ksm(n,P - );
for(int i=;i<n;i++)a[i] = 1LL * a[i] * inv % P;
}
}
inline void inverse(int *a,int *b,int n,int L)
{
if(n == ){b[] = ksm(a[],P - );return;}
inverse(a,b,n>>,L-);
memcpy(c,a,n*sizeof(int));memset(c+n,,n*sizeof(int));
NTT(c,,n<<,L+);NTT(b,,n<<,L+);
for(int i=;i<(n<<);i++) b[i] = 1LL * b[i] * (( - 1LL * c[i] * b[i] % P + P) % P) % P;
NTT(b,-,n<<,L+);memset(b+n,,n*sizeof(int));
}
int main()
{
scanf("%d",&n);
for(INV[] = INV[] = a[] = m=;m<=n;m<<=)L++;
for (int i=; i<=n; i++) INV[i]=P-(LL)INV[P%i]*(P/i)%P;
for (int i=; i<=n; i++) INV[i]=(LL)INV[i-]*INV[i]%P;
for (int i=; i<=n; i++) a[i]=((P-INV[i])<<)%P;
inverse(a,b,m,L);
int ans=b[n];
for (int i=n;i;i--) ans=((LL)ans*i+b[i-])%P;
printf("%d\n",ans);
return ;
}
bzoj 4555 求和的更多相关文章
- [BZOJ 4555][Tjoi2016&Heoi2016]求和
题意 给定 $n$ , 求下式的值: $$ f(n)= \sum_{i=0}^n\sum_{j=0}^i\begin{Bmatrix}i\\ j\end{Bmatrix}\times 2^j\time ...
- BZOJ 4555 Luogu P4091 [HEOI2016/TJOI2016]求和 (第二类斯特林数)
题目链接 (luogu) https://www.luogu.org/problem/P4091 (bzoj) https://www.lydsy.com/JudgeOnline/problem.ph ...
- BZOJ 4555: [Tjoi2016&Heoi2016]求和 [分治FFT 组合计数 | 多项式求逆]
4555: [Tjoi2016&Heoi2016]求和 题意:求\[ \sum_{i=0}^n \sum_{j=0}^i S(i,j)\cdot 2^j\cdot j! \\ S是第二类斯特林 ...
- BZOJ 4555: [Tjoi2016&Heoi2016]求和 [FFT 组合计数 容斥原理]
4555: [Tjoi2016&Heoi2016]求和 题意:求\[ \sum_{i=0}^n \sum_{j=0}^i S(i,j)\cdot 2^j\cdot j! \\ S是第二类斯特林 ...
- BZOJ 4555: [Tjoi2016&Heoi2016]求和 (NTT + 第二类斯特林数)
题意 给你一个数 \(n\) 求这样一个函数的值 : \[\displaystyle f(n)=\sum_{i=0}^{n}\sum_{j=0}^{i} \begin{Bmatrix} i \\ j ...
- 【BZOJ 4555】 4555: [Tjoi2016&Heoi2016]求和 (NTT)
4555: [Tjoi2016&Heoi2016]求和 Time Limit: 40 Sec Memory Limit: 128 MBSubmit: 315 Solved: 252 Des ...
- bzoj 4555 [Tjoi2016&Heoi2016] 求和 —— 第二类斯特林数+NTT
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4555 关于第二类斯特林数:https://www.cnblogs.com/Wuweizhen ...
- BZOJ 4555 [Tjoi2016&Heoi2016]求和 (多项式求逆)
题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=4555 题目大意: 给定 \(S(n,m)\) 表示第二类斯特林数,定义函数 \(f(n ...
- 【BZOJ 4555】[Tjoi2016&Heoi2016]求和 多项式求逆/NTT+第二类斯特林数
出处0.0用到第二类斯特林数的性质,做法好像很多,我打的是直接ntt,由第二类斯特林数的容斥公式可以推出,我们可以对于每一个i,来一次ntt求出他与所有j组成的第二类斯特林数的值,这个时候我们是O(n ...
随机推荐
- SQL server 数据库 操作及简单查询
使用SQL Sever语言进行数据库的操作 常用关键字identity 自增长primary key 主键unique 唯一键not null 非空references 外键(引用) 在使用查询操作数 ...
- HDFS JAVA API介绍
注:在工程pom.xml 所在目录,cmd中运行 mvn package ,打包可能会有两个jar,名字较长的是包含所有依赖的重量级的jar,可以在linux中使用 java -cp 命令来跑.名字较 ...
- Python学习笔记之Python的enumerate函数
Python 的 enumerate() 函数就像是一个神秘的黑箱,你无法简单地用一句话来概括这个函数的作用与用法. enumerate() 函数属于非常有用的高级用法,而对于这一点,很多初学者甚至中 ...
- 【Flask】Flask常用信号
使用信号分为3步,第一是定义一个信号,第二是监听一个信号,第三是发送一个信号. 1. 定义信号:定义信号需要使用到blinker这个包的Namespace类来创建一个命名空间.比如定义一个在访问了某个 ...
- MySQL-5.7 创建及查看触发器
触发器的作用是当表上有对应SQL语句发生时,则触发执行. 1.语法 CREATE [DEFINER = { user | CURRENT_USER }] TRIGGER trigger_name tr ...
- Stalstack 连接管理配置
Stalstack 连接管理配置 注:master端,minion端,配置完成. Saltstack master 测试管理端minion链接状态. salt-key Accepted Keys: ...
- resin服务一直不停重启
resin服务不断重启. 原因为resin配置文件使用域名.需要到服务上绑定一下域名.
- 20145201 《Java程序设计》第四周学习总结
20145201 <Java程序设计>第四周学习总结 教材学习内容总结 本周学习了课本第六.七章内容,即继承与多态.接口与多态. 第六章 继承与多态 6.1 何谓继承 6.1.1 继承共同 ...
- Qt性能问题
使用Qt库开发通信上位机软件,如串口.CAN总线等,涉及到接收界面高速刷新,会使CPU消耗率过高(20%以上),可能还会卡顿. 具体原因不知道,突然想放弃Qt了 ps: 1.问题出在界面刷新,会占据C ...
- ES6 实现阶乘
// 实现一个5的阶乘function factorial(n, acc = 1) { console.log(`n=${n};acc=${acc}`) if(n <= 1) return ac ...