传送门

大意:ACM校队一共有n名队员,从1到n标号,现在n名队员要组成若干支队伍,每支队伍至多有m名队员,求一共有多少种不同的组队方案。两个组队方案被视为不同的,当且仅当存在至少一名队员在两种方案中有不同的队友。

这年头真是……分治FFT都开始烂大街了……

我们来推一推吧

这显然是一个1d1d的DP,用f[i]表示i名队员的方案数

f[i]=∑j=0i−1f[i−j−1]∗Cji−1

即i−1个人里面选j个和i组队(似乎类似strling数)

然后化一下简,便可得到

f[i]=(i−1)!∑j=0i−1f[i−j−1](i−j−1)!∗1j!

一看这不是一个裸的卷积吗?是不是很一颗赛艇!我们就可以用NTT来优化一下了

考虑cdq分治处理[L,R],我们先递归处理[L,Mid],然后把[L,Mid]的f值取出来和(j!)−1来卷一卷。我们就可以得到[L,Mid]对[Mid+1,R]的贡献了。是不是很愉♂快啊!

我不知道其他人怎么写的,比我的慢这么多……

#include <cstdio>
#include <algorithm>
#include <cstring>
#define MAXN 300005
#define LL long long
const LL MOD = 998244353LL, g = 3, T = 262144;
int n, k;
LL w[MAXN], inv[MAXN], invf[MAXN], dp[MAXN], x1[MAXN], x2[MAXN], jc[MAXN], tmp;
inline void Swap(LL &a, LL &b) { tmp=a; a=b; b=tmp; }
LL ksm(LL a, LL k) {
LL ans = 1;
for(; k; k >>= 1) {
if(k&1) ans = ans * a % MOD;
a = a * a % MOD;
}
return ans;
}
inline void Init() {
LL r = ksm(g, (MOD-1)/T); w[0] = 1; invf[0] = inv[0] = invf[1] = inv[1] = jc[1] = 1;
for(int i = 1; i < T; ++ i) w[i] = w[i-1] * r % MOD;
for(int i = 2; i < T; ++ i) jc[i] = jc[i-1] * i % MOD;
for(int i = 2; i < T; ++ i) inv[i] = (MOD-MOD/i) * inv[MOD%i] % MOD;
for(int i = 2; i < T; ++ i) invf[i] = (invf[i-1]*inv[i]) % MOD;
}
inline void NTT(LL *a, int n, int f) {
int i, j, k;
for(i = 0, j = 0; i < n; ++ i) {
if(i > j) Swap(a[i], a[j]);
for(k = (n>>1); (j^=k) < k; k >>= 1);
}
for(i = 1; i < n; i <<= 1)
for(j = 0; j < n; j += i<<1)
for(k = 0; k < i; ++ k) {
LL x = a[j + k], y = w[T/(i<<1)*k] * a[j + k + i] % MOD;
a[j + k] = (x + y) % MOD; a[j + k + i] = (x + MOD - y) % MOD;
}
LL invn;
if(-1 == f) for(std::reverse(a+1, a+n), invn = ksm(n, MOD-2), i = 0; i < n; ++ i) a[i]= a[i] * invn % MOD;
}
void cdq(int L, int R) {
if(L == R) return;
int mid = (L + R) >> 1;
cdq(L, mid);
int len = 1;
for(; len <= (R-L+1); len <<= 1);
for(int i = 0; i < len; ++ i) {
x1[i] = (i < k) ? invf[i] : 0;
x2[i] = (L + i <= mid) ? dp[L + i] : 0;
}
NTT(x1, len, 1); NTT(x2, len, 1);
for(int i = 0; i < len; ++ i) x1[i] = (x1[i] * x2[i]) % MOD;
NTT(x1, len, -1);
for(int i = mid+1; i <= R; ++ i) dp[i] = (dp[i] + x1[i-L-1]*inv[i]) % MOD;
cdq(mid+1, R);
}
int main() {
Init(); int T; scanf("%d", &T);
while(T --) {
scanf("%d%d", &n, &k);
memset(dp, 0, sizeof dp);
dp[0] = 1;
cdq(0, n);
printf("%lld\n", dp[n]*jc[n]%MOD);
}
}

BNUOJ 51279[组队活动 Large](cdq分治+FFT)的更多相关文章

  1. 【BZOJ3456】轩辕朗的城市规划 无向连通图计数 CDQ分治 FFT 多项式求逆 多项式ln

    题解 分治FFT 设\(f_i\)为\(i\)个点组成的无向图个数,\(g_i\)为\(i\)个点组成的无向连通图个数 经过简单的推导(枚举\(1\)所在的连通块大小),有: \[ f_i=2^{\f ...

  2. HDU - 5730 :Shell Necklace(CDQ分治+FFT)

    Perhaps the sea‘s definition of a shell is the pearl. However, in my view, a shell necklace with n b ...

  3. [BZOJ 3456]城市规划(cdq分治+FFT)

    [BZOJ 3456]城市规划(cdq分治+FFT) 题面 求有标号n个点无向连通图数目. 分析 设\(f(i)\)表示\(i\)个点组成的无向连通图数量,\(g(i)\)表示\(i\)个点的图的数量 ...

  4. HDU 5730 Shell Necklace cdq分治+FFT

    题意:一段长为 i 的项链有 a[i] 种装饰方式,问长度为n的相连共有多少种装饰方式 分析:采用dp做法,dp[i]=∑dp[j]*a[i-j]+a[i],(1<=j<=i-1) 然后对 ...

  5. HDU 5730 Shell Necklace(CDQ分治+FFT)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5730 [题目大意] 给出一个数组w,表示不同长度的字段的权值,比如w[3]=5表示如果字段长度为3 ...

  6. 【CF553E】Kyoya and Train 最短路+cdq分治+FFT

    [CF553E]Kyoya and Train 题意:有一张$n$个点到$m$条边的有向图,经过第i条边要花$c_i$元钱,经过第i条边有$p_{i,k}$的概率要耗时k分钟.你想从1走到n,但是如果 ...

  7. Shell Necklace (dp递推改cdq分治 + fft)

    首先读出题意,然后发现这是一道DP,我们可以获得递推式为 然后就知道,不行啊,时间复杂度为O(n2),然后又可以根据递推式看出这里面可以拆解成多项式乘法,但是即使用了fft,我们还需要做n次多项式乘法 ...

  8. HDU Shell Necklace CDQ分治+FFT

    Shell Necklace Problem Description Perhaps the sea‘s definition of a shell is the pearl. However, in ...

  9. HDU5730 Shell Necklace(DP + CDQ分治 + FFT)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5730 Description Perhaps the sea‘s definition of ...

随机推荐

  1. ACM算法模板

    旧版模板下载链接: here 新版的模板目前不提供电子版,正在抽时间做一些修正以及添加一些新内容. 新模板如有需要纸质版的,可以自付打印费进行打印.购买链接:https://weidian.com/i ...

  2. DB2 runstats、reorgchk、reorg 命令

    runstats.reorgchk.reorg 1.runstats runsats可以搜集表的信息,也可以搜集索引信息.作为runstats本身没有优化的功能,但是它更新了统计信息以后,可以让DB2 ...

  3. HDU 5652(二分+广搜)

    题目链接:http://acm.hust.edu.cn/vjudge/contest/128683#problem/E 题目大意:给定一只含有0和1的地图,0代表可以走的格子,1代表不能走的格 子.之 ...

  4. TreeMap的使用

    Map<Integer, String> map = new TreeMap<Integer, String>();//TreeMap本身具有排序功能(默认按键升序排序) ma ...

  5. C# 京东模拟登录小结

    最近有需要模拟京东登录,在解决过程中遇到了一些问题,因此这里记录下来避免以后遇到同样的问题. 首先第一步需要做的是找到登录请求网址和关于请求所需的一些信息.这里可以用抓取工具或者直接用firebug或 ...

  6. aa2

    option = { series : [ { name: 'Map', type: 'map', mapLocation: { x : 'left', y : 'top', height : 500 ...

  7. leetcode解题:Add binary问题

    顺便把之前做过的一个简单难度的题也贴上来吧 67. Add Binary Given two binary strings, return their sum (also a binary strin ...

  8. linux 定时清理session

    php session 运营想让用户登陆网站就能永久保持登陆会话,感觉这是扯淡,因为视频播放1小时,所以我设置了两小时过期. 但是用户过多,导致session文件大量存储.产生上百万千万.服务器空间很 ...

  9. Maven web项目三种运行方式

    http://www.micmiu.com/software/build/maven-web-eclipse-deploy/

  10. mysql 中文乱码解决方法

    最近在.NET 项目中用EF连接mysql,插入中文数据时老是显示乱码,在创建表时都已将编码指定了,但是还是出现乱码,折腾了一阵子才发现在连接字符串里面也要加上指定编码 Character Set=u ...