链接:https://www.nowcoder.com/acm/contest/133/D
来源:牛客网

题目描述

Applese打开了m个QQ群,向群友们发出了组队的邀请。作为网红选手,Applese得到了n位选手的反馈,每位选手只会在一个群给Applese反馈
现在,Applese要挑选其中的k名选手组队比赛,为了维持和各个群的良好关系,每个群中都应有至少一名选手成为Applese的队友(数据保证每个群都有选手给Applese反馈)
Applese想知道,他有多少种挑选队友的方案

输入描述:

输入包括两行
第一行包括三个数n, m, k,表示共有n位选手,m个群,需要有k名选手被选择
第二行包括m个数,第i个数表示第i个群有si个选手
n ≤ 100000, m ≤ k ≤ n

输出描述:

输出包括一行
第一行输出方案数
由于输出可能比较大,你只需要输出在模998244353意义下的答案
示例1

输入

5 3 4
1 2 2

输出

4

思路分析: dp[i][j] 表示前 i 个QQ 群中选了 j 个人的方案数,并且保证每个群中至少选 1 人
    dp[i][j] += dp[i-1][j-h]*C(x, h) , 其实本质意思就是第一个群选 1个, 2个,... n 个所对应的方案 * 第二个群选 1个, 2个, ... n个,这不就是个多项式的乘法吗,又因为其带模数,所以一个NTT,就可以了
代码示例 :
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const ll maxn = 1e5+5;
const ll mod = 998244353;
ll n, m, k;
vector<ll>ve[maxn];
ll pp[maxn], inv[maxn]; ll qw(ll a, ll b){
ll res = 1;
a %= mod;
while(b){
if (b&1) res = res*a%mod;
a = a*a%mod;
b >>= 1;
}
return res;
} ll C(ll n, ll m){
ll ans = pp[n]*inv[m]%mod*inv[n-m]%mod;
return ans;
} ll rev (ll x, ll len){
ll ret = 0;
for(ll i = 0; (1<<i)<len; i++){
ret <<= 1;
if ((1<<i)&x) ret |= 1;
}
return ret;
} void NTT(vector<ll>& p, ll len, ll DFT){
for(ll i = 0; i < len; i++){
ll x= rev(i, len);
if (i < x) swap(p[i], p[x]);
}
for(ll i = 1; i < len; i <<= 1){
ll wn = qw(3, (mod-1)/(2*i));
if (DFT == -1) wn = qw(wn, mod-2);
for(ll j = 0; j < len; j += i*2){
ll w = 1;
for(ll k = 0; k < i; k++){
ll x = p[j+k];
ll y = w*p[j+k+i]%mod;
p[j+k]=(x+y)%mod;
p[j+k+i]=(x-y+mod)%mod;
w = w*wn%mod;
}
}
}
if (DFT == -1)
for(ll i = 0, x = qw(len, mod-2); i < len; i++)
p[i]=p[i]*x%mod;
} void mul(vector<ll>& a, vector<ll> b){
ll n = a.size(), m = b.size();
ll len = 1;
while(len < (n+m)) len <<= 1;
a.resize(len);
b.resize(len);
NTT(a, len, 1);
NTT(b, len, 1);
for(ll i = 0; i < len; i++) a[i] = a[i]*b[i]%mod;
NTT(a, len, -1);
a.resize(n+m);
} queue<ll>que;
int main() {
ll x;
pp[0] = 1;
for(ll i = 1; i <= 100000; i++) pp[i]=pp[i-1]*i%mod;
for(ll i = 0; i <= 100000; i++) inv[i]=qw(pp[i],mod-2); cin >> n >> m >> k;
for(ll i = 1; i <= m; i++){
scanf("%lld", &x);
ve[i].resize(x);
for(ll j = 0; j < x; j++) ve[i][j] = C(x, j+1); // 下标从0开始
que.push(i);
}
while(que.size() > 1){
ll u = que.front(); que.pop();
ll v = que.front(); que.pop();
mul(ve[u], ve[v]);
que.push(u);
}
printf("%lld\n", ve[que.front()][k-m]);
//for(ll i = 0; i <= ve[que.front()].size(); i++) printf("++%lld %lld \n",i, ve[que.front()][i]);
return 0;
}

NTT - 牛客的更多相关文章

  1. 2018牛客网暑假ACM多校训练赛(第三场)D Encrypted String Matching 多项式 FFT

    原文链接https://www.cnblogs.com/zhouzhendong/p/NowCoder-2018-Summer-Round3-D.html 题目传送门 - 2018牛客多校赛第三场 D ...

  2. 牛客小白月赛2 I 艺 【归并思想】【离散化】

    链接:https://www.nowcoder.com/acm/contest/86/I来源:牛客网 题目描述 接下去,Sεlιнα(Selina) 又搞了个文艺竞演. 虽说是文艺竞演,其实只是为了满 ...

  3. 牛客小白月赛12 J 月月查华华的手机 (序列自动机模板题)

    链接:https://ac.nowcoder.com/acm/contest/392/J 来源:牛客网 题目描述 月月和华华一起去吃饭了.期间华华有事出去了一会儿,没有带手机.月月出于人类最单纯的好奇 ...

  4. 牛客网程序员面试金典:1.1确定字符互异(java实现)

    问题描述: 请实现一个算法,确定一个字符串的所有字符是否全都不同.这里我们要求不允许使用额外的存储结构. 给定一个string iniString,请返回一个bool值,True代表所有字符全都不同, ...

  5. 牛客网 --java问答题

    http://www.nowcoder.com/ 主要是自己什么都不怎么会.在这里可以学习很多的! 第一天看题自己回答,第二天看牛客网的答案! 1 什么是Java虚拟机?为什么Java被称作是“平台无 ...

  6. 【面试笔试算法】牛客网一站通Offer编程题2016.4.19

    牛客网一站通offer (一)字符串变形 1. 题目: 对于一个给定的字符串,我们需要在线性(也就是O(n))的时间里对它做一些变形.首先这个字符串中包含着一些空格,就像"Hello Wor ...

  7. 牛客网《BAT面试算法精品课》学习笔记

    目录 牛客网<BAT面试算法精品课>学习笔记 牛客网<BAT面试算法精品课>笔记一:排序 牛客网<BAT面试算法精品课>笔记二:字符串 牛客网<BAT面试算法 ...

  8. 牛客小白月赛13 小A买彩票 (记忆化搜索)

    链接:https://ac.nowcoder.com/acm/contest/549/C来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言52428 ...

  9. 牛客小白月赛13-J小A的数学题 (莫比乌斯反演)

    链接:https://ac.nowcoder.com/acm/contest/549/J来源:牛客网 题目描述 小A最近开始研究数论题了,这一次他随手写出来一个式子,∑ni=1∑mj=1gcd(i,j ...

随机推荐

  1. UVA 11107 Life Forms——(多字符串的最长公共子序列,后缀数组+LCP)

    题意: 输入n个序列,求出一个最大长度的字符串,使得它在超过一半的DNA序列中连续出现.如果有多解,按照字典序从小到大输出所有解. 分析:这道题的关键是将多个字符串连接成一个串,方法是用不同的分隔符把 ...

  2. BZOJ 4236 "JOIOJI"(前缀和+map+pair)

    传送门: [1]:BZOJ [2]:洛谷 •题解 定义数组 a,b,c 分别表示 'J' , 'O' , 'I' 的前缀和: 要想使区间 (L,R] 满足条件当且仅当 a[R]-a[L] = b[R] ...

  3. windows命令行下redis读取中文字符乱码

    我在eclipse上对redis进行了一个操作,添加了一个中文字符串进去,可以看到是添加成功了的 但是在命令行中读取的时候却成了乱码,如下图所示 这是因为windows命令行的编码是gbk 可以通过如 ...

  4. 【u105】路径计数2

    Time Limit: 1 second Memory Limit: 128 MB [问题描述] 一个N×N的网格,你一开始在(1, 1),即左上角.每次只能移动到下方相邻的格子或者右方相邻的格子,问 ...

  5. php连接数据库并创建数据库表

    先开启本地服务器 1.输入localhost/phpmyadmin 查看本地数据库是否安装 2.在本地服务器上建一个文件夹,里面建一个php文件(如test.php) 3.连接数据库 4.在浏览器上输 ...

  6. Apply,Call,bind对比

    apply.call call和apply都是为了改变上下文背景存在的,即改变函数内部指向 javascript一大特点是函数存在定义时的上下文,运行时的上下文和上下文可改变的概念 apply.cal ...

  7. 2019-2-27-win10-uwp-去掉-Flyout-边框

    title author date CreateTime categories win10 uwp 去掉 Flyout 边框 lindexi 2019-02-27 17:48:46 +0800 201 ...

  8. Linux 内核使用 USB 数据函数

    USB 核心中的几个帮忙函数可用来从所有的 USB 设备中存取标准信息. 这些函数不能从 中断上下文或者持有自旋锁时调用. 函数 usb_get_descriptor 获取指定的 USB 描述符从特定 ...

  9. SDOI2019热闹又尴尬的聚会

    P5361 [SDOI2019]热闹又尴尬的聚会 出题人用脚造数据系列 只要将\(p\)最大的只求出来,\(q\)直接随便rand就能过 真的是 我们说说怎么求最大的\(p\),这个玩意具有很明显的单 ...

  10. QP简介

    QP简介 QP(Quantum Platform)是一个轻量级的.开源的.基于状态机的.事件驱动型应用程序框架.这个框架包括四部分: 事件处理器(QEP): 轻量级的事件驱动框架(QF): 任务调度微 ...