[题解] Atcoder ABC 225 H Social Distance 2 生成函数,分治FFT
题目
首先还没有安排座位的\(m-k\)个人之间是有顺序的,所以先把答案乘上\((m-k)!\),就可以把这些人看作不可区分的。
已经确定的k个人把所有座位分成了k+1段。对于第i段,如果我们能求出这一段恰好额外坐j人时的代价总和\(f_{i,j}\),并令\(f_{i,j}\)的普通生成函数为\(F_i(x)\),答案就是\(\prod F_i(x)\)的\(m-k\)次项系数。
先考虑k+1段中两边都有已经确定的人的k-1段。对于每一段i,枚举其中额外坐的人数j,现在考虑求出\(f_{i,j}\)。令\(g_i\)表示只考虑两个相邻的人,他们之间的距离为i时的代价,显然\(g_i=i\)。令\(G(x)\)为g的普通生成函数:
G(x)&=\sum_{n>0}n\cdot x^n\\
&=x\sum_{n\geq0}(n+1)x^n\\
&=x \cdot \frac1{(1-x)^2}\\
&=\frac x {(1-x)^2}\\
\end{align}
\]
令第i段空座位两边端点之间的距离为len,发现\(f_{i,j}=G(x)^{j+1}\)的len次项系数(每j个人有j+1段空隙)。由于\(n\leq2e5\),所以可以对每一个j(\(j\geq0\))用这个公式暴力算:\(\frac{1}{(1-x)^m}=\sum_{n\geq0}\binom{n+m-1}{m-1}x^n\)。
考虑序列两头只有一边有已经确定的人的段。这里\(f_{i,j}=G(x)^j\)的0~len次项系数之和。根据上面的公式,我们实际要求的是一个组合数前缀和的形式。\(C(n,n)+C(n+1,n)+C(n+2,n)+\cdots+C(m,n)=C(m+1,n+1)\),可以根据这个直接\(O(1)\)算。
对于k=0的情况特殊处理,方法和上面处理序列两头的类似。
所以现在已经算出了每一段的\(F(x)\),项数之和是\(O(n)\)的,用分治FFT把所有\(F(x)\)卷起来即可。卷之前把所有\(F(x)\)顺序打乱,防止分治的时候被卡。时间复杂度\(O(nlog^2n)\)。
点击查看代码
#include <bits/stdc++.h>
#include <atcoder/all>
#define rep(i,n) for(int i=0;i<n;++i)
#define repn(i,n) for(int i=1;i<=n;++i)
#define LL long long
#define pii pair <int,int>
#define fi first
#define se second
#define mpr make_pair
#define pb push_back
using namespace std;
using mint=atcoder::modint998244353;
const LL MOD=998244353;
LL qpow(LL x,LL a)
{
LL res=x,ret=1;
while(a>0)
{
if((a&1)==1) ret=ret*res%MOD;
a>>=1;
res=res*res%MOD;
}
return ret;
}
LL n,m,k,a[200010],fac[400010],inv[400010];
vector <vector <mint> > v;
LL C(LL nn,LL mm){return fac[nn]*inv[mm]%MOD*inv[nn-mm]%MOD;}
void deal(LL emp)
{
if(emp<=0) return;
vector <mint> tmp;tmp.pb(1);
repn(seg,emp) tmp.pb(C(emp+seg,seg+seg));
v.pb(tmp);
}
vector <mint> solve(LL lb,LL ub)
{
if(lb==ub) return v[lb];
return atcoder::convolution(solve(lb,(lb+ub)/2),solve((lb+ub)/2+1,ub));
}
int main()
{
fac[0]=1;repn(i,400005) fac[i]=fac[i-1]*(LL)i%MOD;
rep(i,400003) inv[i]=qpow(fac[i],MOD-2);
cin>>n>>m>>k;
rep(i,k) scanf("%lld",&a[i]);
if(k==0)
{
LL seg=m-1,res=0;
for(LL len=m-1;len<n;++len) (res+=C(len+seg-1,seg+seg-1)*(n-len))%=MOD;
cout<<res*fac[m]%MOD<<endl;
return 0;
}
rep(i,k-1)
{
LL len=a[i+1]-a[i];
vector <mint> tmp;
repn(seg,len)
{
LL val=C(len+seg-1,seg+seg-1);
tmp.pb(val);
}
v.pb(tmp);
}
deal(a[0]-1);deal(n-a[k-1]);
random_shuffle(v.begin(),v.end());
vector <mint> ans=solve(0,v.size()-1);
cout<<(LL)ans[m-k].val()*fac[m-k]%MOD<<endl;
return 0;
}
[题解] Atcoder ABC 225 H Social Distance 2 生成函数,分治FFT的更多相关文章
- [题解] Atcoder ABC 213 H Stroll DP,分治FFT
题目 令\(dp_{i,j}\)表示从点1到达点i,路径长度为j的方案数.转移为\(dp_{i,j}=\sum_{(i,v,w)\in E}dp_{v,j-w}p_{i,v,w}\). 显然只能从长度 ...
- AtCoder ABC 242 题解
AtCoder ABC 242 题解 A T-shirt 排名前 \(A\) 可得 T-shirt 排名 \([A+1,B]\) 中随机选 \(C\) 个得 T-shirt 给出排名 \(X\) ,求 ...
- atcoder abc 244
atcoder abc 244 D - swap hats 给定两个 R,G,B 的排列 进行刚好 \(10^{18}\) 次操作,每一次选择两个交换 问最后能否相同 刚好 \(10^{18}\) 次 ...
- AtCoder ABC 250 总结
AtCoder ABC 250 总结 总体 连续若干次一样的结果:30min 切前 4 题,剩下卡在 T5 这几次卡在 T5 都是一次比一次接近, 什么 dp 前缀和打挂,精度被卡,能水过的题连水法都 ...
- ATCODER ABC 099
ATCODER ABC 099 记录一下自己第一场AK的比赛吧...虽然还是被各种踩... 只能说ABC确实是比较容易. A 题目大意 给你一个数(1~1999),让你判断它是不是大于999. Sol ...
- Atcoder ABC 141
Atcoder ABC 141 A - Weather Prediction SB题啊,不讲. #include<iostream> #include<cstdio> #inc ...
- Atcoder ABC 139E
Atcoder ABC 139E 题意: n支球队大循环赛,每支队伍一天只能打一场,求最少几天能打完. 解法: 考虑抽象图论模型,既然一天只能打一场,那么就把每一支球队和它需要交手的球队连边. 求出拓 ...
- Atcoder ABC 139D
Atcoder ABC 139D 解法: 等差数列求和公式,记得开 $ long long $ CODE: #include<iostream> #include<cstdio> ...
- Atcoder ABC 139C
Atcoder ABC 139C 题意: 有 $ n $ 个正方形,选择一个起始位置,使得从这个位置向右的小于等于这个正方形的高度的数量最多. 解法: 简单递推. CODE: #include< ...
随机推荐
- NFS配置-实现多服务器共享目录
NFS网络文件系统 为什么要用NFS? 前端所有的应用服务器接收到用户上传的图片.文件.视频,都会统一放到后端的存储上.共享存储的好处:方便数据的查找与取出,缺点:存储服务器压力大,坏了丢失全部数据. ...
- 第八天pyhton3 函数的返回值、作用域
返回值 pthon函数使用return语句返回"返回值": 所有函数都有返回值,如果没有return语句,隐式调用return None: return 语句并不一定是函数的语句块 ...
- 2499-springboot使用jar形式打包在linux上运行
由于maven使用的种种问题,以前springboot版本变化较快带来的一些不兼容问题,是否考虑下使用jar形式运行web程序,而不是固守于war包与tomcat: 主要原理有两点: 使用nohup来 ...
- CF280D k-Maximum Subsequence Sum(线段树)
在做这题时我一开始把\(tag\)写入了结构体 #include <iostream> #include <cstdio> #include <cstring> # ...
- Redis 09 基数
参考源 https://www.bilibili.com/video/BV1S54y1R7SB?spm_id_from=333.999.0.0 版本 本文章基于 Redis 6.2.6 概述 Redi ...
- Redis架构之哨兵机制与集群
Redis架构之哨兵机制与集群 哨兵机制 1.介绍: Sentinel(哨兵)是redis高可用性解决方案:由一个或多个由一个或多个Sentinel 实例 组成的Sentinel 系统可以监视任意多个 ...
- 谈谈你对Promise的理解
一.Promise是什么? 理解 抽象表达: Promise 是一门新的技术(ES6 规范) Promise 是 JS 中进行异步编程的新解决方案(备注:旧方案是单纯使用回调函数) 具体表达: 从语法 ...
- 报错:①Tog goal specified requires a project to execute but there is no POM in this directory......②说类HelloWorld是公共的, 应在名为 HelloWorld.java 的文件中声明 public class HelloWorld......
在运行Maven的命令时,在DOS窗口里面必须把目录切换到项目的根部,要不然命令是找不到目的地. 下图是错误示范,项目在Demo02这个目录里,就必须将目录切换到Demo02下,否则DOS窗口只有飘红 ...
- 第五十一篇:webpack中的loader(二) --less-loader
好家伙 先扩充一下知识点: 什么是.less文件? 作为一名前端开发的同学,很多时候我们都无法避免地要去写大量的 CSS 代码, 而且耗费的时间还不少,所以学习一种能够提升开发效率的 CSS 预处理器 ...
- KingbaseES V8R6C5集群部署启动securecmdd服务配置案例
案例说明: 对于KingbaseES V8R6C5版本在部集群时,需要建立kingbase.root用户在节点间的ssh互信,如果在生产环境禁用root用户ssh登录,则通过ssh部署会失败:在图形化 ...