洛谷 P2791 幼儿园篮球题
洛谷 P2791 幼儿园篮球题
https://www.luogu.org/problemnew/show/P2791
我喜欢唱♂跳♂rap♂篮球
要求的是:\(\sum_{i=0}^kC_m^iC_{n-m}^{k-i}i^L\)
这个\(i^L\)很烦,就把第二类斯特林数的式子套进去
\(\sum_{i=0}^kC_m^iC_{n-m}^{k-i}i^L\)
\(\sum_{i=0}^kC_m^iC_{n-m}^{k-i}\sum_{j=0}^iC_{i}^j\begin{Bmatrix}L\\j\end{Bmatrix}j!\)
\(\sum_{j=0}^k\begin{Bmatrix}L\\j\end{Bmatrix}j!\sum_{i=j}^kC_m^iC_{n-m}^{k-i}C_{i}^j\)
后面\(\sum\)三个组合数好像很不好搞,但是\(C_{m}^{i}C_{i}^{j}=C_{m}^{j}C_{m-j}^{i-j}\),可以拆出一个与\(i\)无关的组合数
\(\sum_{j=0}^k\begin{Bmatrix}L\\j\end{Bmatrix}j!C_{m}^{j}\sum_{i=j}^kC_{m-j}^{i-j}C_{n-m}^{k-i}\)
把式子化的好看一点,发现可以套范德蒙德卷积(\(\sum_{i=0}^kC_{n}^{i}C_{m}^{k-i}=C_{n+m}^k\))
\(\sum_{j=0}^k\begin{Bmatrix}L\\j\end{Bmatrix}j!C_{m}^{j}\sum_{i=0}^kC_{m-j}^{k-i-j}C_{n-m}^{i}\)
\(\sum_{j=0}^k\begin{Bmatrix}L\\j\end{Bmatrix}j!C_{m}^{j}C_{n-j}^{k-j}\)
注意上面循环\(i\)的上界实际上是\(\min(k,L,m)=O(L)\)
求出\(n=L\)的一行第二类斯特林数,每次询问就可以\(O(L)\)了
把组合数全拆出来约分就洛谷rk1了= =
#include<bits/stdc++.h>
#define il inline
#define vd void
#define mod 998244353
#define poly std::vector<int>
typedef long long ll;
il ll gi(){
ll x=0,f=1;
char ch=getchar();
while(!isdigit(ch))f^=ch=='-',ch=getchar();
while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
return f?x:-x;
}
il int pow(int x,int y){
int ret=1;
while(y){
if(y&1)ret=1ll*ret*x%mod;
x=1ll*x*x%mod;y>>=1;
}
return ret;
}
#define maxn 524289
poly pA,pB;
int rev[maxn],_lstN,P[maxn],iP[maxn];
il vd ntt(int*A,int N,int t){
for(int i=0;i<N;++i)if(rev[i]>i)std::swap(A[i],A[rev[i]]);
for(int o=1;o<N;o<<=1){
int W=t?P[o]:iP[o];
for(int*p=A;p!=A+N;p+=o<<1)
for(int i=0,w=1;i<o;++i,w=1ll*w*W%mod){
int t=1ll*w*p[i+o]%mod;
p[i+o]=(p[i]-t+mod)%mod;p[i]=(p[i]+t)%mod;
}
}
if(!t){
int inv=pow(N,mod-2);
for(int i=0;i<N;++i)A[i]=1ll*A[i]*inv%mod;
}
}
int N,lg;
il vd setN(int n){
N=1,lg=0;
while(N<n)N<<=1,++lg;
if(N!=_lstN)for(int i=0;i<N;++i)rev[i]=(rev[i>>1]>>1)|((i&1)<<lg-1);
}
il vd ntt(poly&a,int t){
static int A[maxn];
for(int i=0;i<a.size();++i)A[i]=a[i];memset(A+a.size(),0,4*(N-a.size()));
ntt(A,N,t);
a.resize(N);
for(int i=0;i<N;++i)a[i]=A[i];
int s=a.size();while(s&&!a[s-1])--s;
a.resize(s);
}
il poly mul(poly a,poly b,int newn=-1){
if(newn==-1)newn=a.size()+b.size()-1;
setN(a.size()+b.size()-1);
ntt(a,1),ntt(b,1);
for(int i=0;i<N;++i)a[i]=1ll*a[i]*b[i]%mod;
ntt(a,0);a.resize(newn);
return a;
}
il poly operator+(poly a,const poly&b){
if(a.size()<b.size())a.resize(b.size());
for(int i=0;i<a.size();++i)if(i<b.size())a[i]=(a[i]+b[i])%mod;
return a;
}
il poly operator-(poly a,const poly&b){
if(a.size()<b.size())a.resize(b.size());
for(int i=0;i<a.size();++i)if(i<b.size())a[i]=(a[i]-b[i]+mod)%mod;
return a;
}
il poly operator*(poly a,int b){
for(auto&i:a)i=1ll*i*b%mod;
return a;
}
il poly qiudao(poly a){
for(int i=0;i<a.size()-1;++i)a[i]=1ll*a[i+1]*(i+1)%mod;
a.erase(a.end()-1);
return a;
}
il poly jifen(poly a){
a.insert(a.begin(),0);
for(int i=1;i<a.size();++i)a[i]=1ll*a[i]*pow(i,mod-2)%mod;
return a;
}
il poly getinv(poly a){
if(a.size()==1)return poly(1,pow(a[0],mod-2));
int n=a.size(),m=a.size()+1>>1;
poly _a(m);
for(int i=0;i<m;++i)_a[i]=a[i];
poly b=getinv(_a);
setN(n+m*2-2);
ntt(a,1);ntt(b,1);
for(int i=0;i<N;++i)a[i]=1ll*a[i]*b[i]%mod*b[i]%mod;
ntt(a,0),ntt(b,0);
a.resize(n);
return b*2-a;
}
il poly getln(poly a,int n=-1){
if(n==-1)n=a.size();
a.resize(n);
return jifen(mul(qiudao(a),getinv(a),n));
}
il poly getexp(poly a){
if(a.size()==1)return a[0]=1,a;
int n=a.size(),m=a.size()+1>>1;
poly _a(m);
for(int i=0;i<m;++i)_a[i]=a[i];
poly b=getexp(_a);
return mul(b,poly(1,1)-getln(b,a.size())+a,a.size());
}
il poly operator^(poly a,int b){
int n=a.size();
a=getexp(getln(a)*b);a.resize(n);
return a;
}
il poly sqrt(poly a){
if(a.size()==1)return a;
int n=a.size(),m=a.size()+1>>1;
poly _a(m);
for(int i=0;i<m;++i)_a[i]=a[i];
poly b=sqrt(_a);b.resize(n);
return (b+mul(a,getinv(b),n))*(mod+1>>1);
}
il vd poly_init(){
int G=3,iG=332748118;
for(int i=1;i<maxn;i<<=1)P[i]=pow(G,(mod-1)/(i<<1)),iP[i]=pow(iG,(mod-1)/(i<<1));
}
il vd add(int&a,int b){a=a+b>=mod?a+b-mod:a+b;}
int fact[20000010],ifact[20000010];
int pr[4000010],Pr,PL[20000010];
bool yes[20000010];
int main(){
#ifdef XZZSB
freopen("in.in","r",stdin);
freopen("out.out","w",stdout);
#endif
poly_init();
int N=gi(),M=gi(),S=gi(),L=gi(),o=std::max(N,L);
fact[0]=1;for(int i=1;i<=o;++i)fact[i]=1ll*i*fact[i-1]%mod;
ifact[o]=pow(fact[o],mod-2);for(int i=o-1;~i;--i)ifact[i]=1ll*ifact[i+1]*(i+1)%mod;
PL[0]=0,PL[1]=1;
for(int i=2;i<=L;++i){
if(!yes[i])pr[++Pr]=i,PL[i]=pow(i,L);
for(int j=1;j<=Pr&&i*pr[j]<=L;++j){
yes[i*pr[j]]=1;
PL[i*pr[j]]=1ll*PL[pr[j]]*PL[i]%mod;
if(i%pr[j]==0)break;
}
}
poly f(L+1),g(L+1);
for(int i=0,mul=1;i<=L;++i,mul=mod-mul)f[i]=1ll*mul*ifact[i]%mod;
for(int i=0;i<=L;++i)g[i]=1ll*PL[i]*ifact[i]%mod;
f=mul(f,g,L+1);
while(S--){
int n=gi(),m=gi(),k=gi(),ans=0,o=std::min(k,std::min(m,L));
for(int i=0;i<=o;++i)
ans=(ans+1ll*f[i]*ifact[m-i]%mod*fact[n-i]%mod*ifact[k-i])%mod;
printf("%d\n",1ll*ans*fact[m]%mod*fact[k]%mod*ifact[n]%mod);
}
return 0;
}
洛谷 P2791 幼儿园篮球题的更多相关文章
- 洛谷 P2791 - 幼儿园篮球题(第二类斯特林数)
题面传送门 首先写出式子: \[ans=\sum\limits_{i=0}^m\dbinom{m}{i}\dbinom{n-m}{k-i}·i^L \] 看到后面有个幂,我们看它不爽,因此考虑将其拆开 ...
- luogu P2791 幼儿园篮球题
传送门 先看我们要求的是什么,要求的期望就是总权值/总方案,总权值可以枚举进球的个数\(i\),然后就应该是\(\sum_{i=0}^{k} \binom{m}{i}\binom{n-m}{k-i}i ...
- 【洛谷2791】幼儿园篮球题(第二类斯特林数,NTT)
[洛谷2791]幼儿园篮球题(第二类斯特林数,NTT) 题面 洛谷 题解 对于每一组询问,要求的东西本质上就是: \[\sum_{i=0}^{k}{m\choose i}{n-m\choose k-i ...
- 【题解】幼儿园篮球题(范德蒙德卷积+斯特林+NTT)
[题解]幼儿园篮球题(NTT+范德蒙德卷积+斯特林数) 题目就是要我们求一个式子(听说叫做超几何分布?好牛逼的名字啊) \[ \sum_{i=1}^{S}\dfrac 1 {N \choose n_i ...
- 洛谷 P2220 [HAOI2012]容易题 数论
洛谷 P2220 [HAOI2012]容易题 题目描述 为了使得大家高兴,小Q特意出个自认为的简单题(easy)来满足大家,这道简单题是描述如下: 有一个数列A已知对于所有的A[i]都是1~n的自然数 ...
- 在洛谷3369 Treap模板题 中发现的Splay详解
本题的Splay写法(无指针Splay超详细) 前言 首先来讲...终于调出来了55555...调了整整3天..... 看到大部分大佬都是用指针来实现的Splay.小的只是按照Splay的核心思想和原 ...
- 洛谷 P4145 上帝造题的七分钟2 / 花神游历各国
洛谷 这题就是区间开根号,区间求和.我们可以分块做. 我们记布尔数组vis[i]表示第i块中元素是否全部为1. 因为显然当一个块中元素全部为1时,并不需要对它进行根号操作. 我们每个块暴力开根号,因为 ...
- Luogu2791 幼儿园篮球题【斯特林数,数学】
题目链接:洛谷 我一开始不知道$N,M$有什么用处,懵逼了一会儿,结果才发现是输入数据范围... $$\begin{aligned}\binom{n}{k}Ans&=\sum_{i=0}^k\ ...
- 【洛谷2791】 幼儿园篮球题 第二类斯特林数+NTT
求 \(\sum_{i=0}^{k}\binom{m}{i}\binom{n-m}{k-i}i^L\) \((1\leqslant n,m\leqslant 2\times 10^7,1\leqsla ...
随机推荐
- ApachShiro 一个系统 两套验证方法-(后台管理员登录、前台App用户登录)同一接口实现、源码分析
需求: 在公司新的系统里面博主我使用的是ApachShiro 作为安全框架.作为后端的鉴权以及登录.分配权限等操作 管理员的信息都是存储在管理员表 前台App 用户也需要校验用户名和密码进行登录.但是 ...
- C# ——Parallel类
一.Parallel类 Parallel类提供了数据和任务的并行性: 二.Paraller.For() Paraller.For()方法类似于C#的for循环语句,也是多次执行一个任务.使用Paral ...
- debug 查询服务日志,用于定位服务在运行和启动过程中出现的问题
vim /usr/lib/systemd/system/sshd.service [Unit] Description=OpenSSH server daemon Documentation=man: ...
- sharepoint中的Power Shell命令创建、删除文档库列表
ListTemplateType 枚举: 自定义列表-GenericList.文档库-DocumentLibrary.图片库-PictureLibrary.公告-Announcements.联系人-C ...
- PCL提取圆柱系数
网上看了很多教程,没看到圆柱提取后的系数解释. 源码如下: #include <pcl/ModelCoefficients.h> #include <pcl/io/pcd_io.h& ...
- aiohttp你不知道的异步操作网络请求
aiohttp支持异步操作的网络请求的模块 1.一个简单异步协程爬取 read() text(encoding=编码) 比如:await r.text(encoding="utf-8&quo ...
- MySQL JOIN 连接时,条件为以逗号分隔的字段与 ID 相匹配
一.背景 有一张相片表,一张相片所属标签表,一张相片可以归属于多个标签,表结构如下: 现在需要通过一次查询,得到每一张照片对应的标签名称,标签名称之间以固定的分隔符连接,结果如下图: 二.查询语句 原 ...
- Jmeter学习笔记(八)——监听器元件之聚合报告
1.聚合报告添加 聚合报告是常用的监听器之一,添加路径: 点击线程组->添加->监听器->聚合报告 2.聚合报告界面及说明 Label:请求的名称,就是我们在进行测试的httpreq ...
- Vue检测当前是否处于mock模式
Vue检测当前是否处于mock模式 1.在main.js中声明全局变量: import Vue from 'vue' /* 全局变量 */ var GLOBAL_VARIABLE = { isMock ...
- Go数据类型之复合数据类型--数组
3.1数组 数组是一个由固定长度的特定类型元素组成的序列,一个数组可以由零个或多个元素组成.数组中每个元素类型相同,又是连续分配,因此可以以固定的速度索引数组中的任何数据,速度非常快. 3.1.1声明 ...