首页 > 其他分享 >[MdOI R5] Many Minimizations & [ARC164F] Many Increasing Problems 题解

[MdOI R5] Many Minimizations & [ARC164F] Many Increasing Problems 题解

时间:2024-06-23 19:59:19浏览次数:26  
标签:Minimizations int Many sum 自然数 infin 题解 include

讲下一个思路比较自然的基于自然数幂和的 \(O(n\log n)\) 且复杂度与 \(m\) 几乎无关的做法。

不难发现让我们计数的问题是保序回归 \(L_1\) 中一条链的情况。这个情况有一个简单的 slope-trick 做法:用堆维护斜率,每次 push 进去两个当前的数,然后 pop 出一个最大值。最终所有数的和减去堆中的数的和就是答案。

有一个来自 ARC128F 经典思维技巧:对于这类弹堆压堆还要求堆中元素和的计数问题,考虑转化成值域为 01 的问题。即活用 \(i=\sum_{x=1}^{\infin} [i\ge x]\) 的等式。将 \(\ge x\) 的数标成 \(1\),剩余的数标成 \(0\)。那么如果原先堆中有 \(s\) 个 \(1\),遇到一个 \(1\) 会变成一个 \(s+1\),遇到一个 \(0\) 会变成 \(\max(s-1,0)\)。这就是一个格路游走问题,容易验证最终 \(s\) 的值等于路程中 \(1\) 的个数减去路程中 \(0\) 的个数再加上如果没有对 \(0\) 取 \(\max\) 的情况下,\(s\) 在整个过程中的最小值。

发现唯一难算的就是最后一部分的“最小值之和”。考虑继续运用上面的思维技巧,继续活用等式 \(i=\sum_{x=1}^{\infin} [i\ge x]\),将 \(s\) 的游走过程看作 \((0,0)\) 到 \((n,\times)\) 的游走过程,那么最小值之和(的相反数)可以拆成触碰 \(y=-t\ (t>0)\) 这条线的方案数之和。钦定触碰一条线的格路游走就是我们熟悉的反射容斥。我们设原来有 \(p\) 个 \(1\),那么原先终点在 \((n,2p-n)\),如果 \(2p-n>t\) 则经过那条线的方案数等于到终点 \((n,-2t-2p+n)\) 的方案数。

所以对于一个固定的 \(p\),我们需要对以下东西求和:

\[S_p=\sum_{t=1}^{\infin} {n\choose \min(n-t-p,p)} \]

这个可以预处理 \({n\choose \times}\) 这一行的组合数前缀和简单算出来。

现在考虑对于 \(x\) 你需要依次带入 \(x=1,2,\dots,m\),不妨把结果看成一个关于 \(x\) 的多项式,则这个多项式实际上是:

\[F(x)=\sum_{p=0}^n x^p(m-x)^{n-p}S_p \]

展开 \((m-x)^{n-p}\),容易发现可以用一遍卷积求出 \(F\)。

最后我们只需要解决 \(\sum_{i=1}^m F(i)\),相当于要对一个固定的 \(n\) 求出 \(k=0,1,2,\dots,n\) 的自然数幂和 \(S_k(n)=\sum_{i=0}^n i^k\),可以用多项式求逆求出伯努利数,然后卷一次得到自然数幂和。于是我们就做到复杂度 \(O(n\log n)\)。

关于伯努利数求自然数幂和:

写给自己看的备忘笔记:伯努利数感觉还是直接生成函数定义更好理解。其 EGF 为 \(B=\frac{x}{e^x-1}\)。可以对 \(\sum_{i=0}^{\infin} \frac{1}{(i+1)!}x^i\) 多项式求逆单 \(\log\) 求得。

对于自然数幂和,我们考虑研究其关于 \(k\) 的 EGF:

\[\begin{aligned} G_n&=\sum_{k=0}^{\infin} \frac{S^k(n)}{k!}x^k \\ &=\sum_{k=0}^{\infin} \sum_{i=0}^n \frac{1}{k!} i^k x^k \end{aligned} \]

#include <cstdio>
#include <vector>
#include <cassert>
#include <algorithm>
// headers
struct poly{/** my poly template **/};
int n,m;
const int N=100103;
int fac[N],fiv[N];
int arr[N],pre[N];
int coe[N],pw[N];
inline int C(int a,int b){return (ll)fac[a]*fiv[b]%P*fiv[a-b]%P;}
void calc(int lim){
	pw[0]=1;
	for(int i=1;i<=lim;++i) pw[i]=(ll)pw[i-1]*m%P;
	fac[0]=1;
	for(int i=1;i<=lim;++i) fac[i]=(ll)fac[i-1]*i%P;
	fiv[lim]=qp(fac[lim]);
	for(int i=lim;i;--i) fiv[i-1]=(ll)fiv[i]*i%P;
}
int main(){
	n=read();m=read();
	calc(n+3);int res=(ll)n*(m-1)%P*pw[n]%P;
	if(res&1) res+=P;
	res>>=1;
	pre[0]=1;
	for(int i=1;i<=n;++i){
		pre[i]=pre[i-1]+C(n,i);
		if(pre[i]>=P) pre[i]-=P;
	}
	poly F(n+1),G(n+1);
	for(int i=0;i<=n;++i){
		if(2*i<=n) F[i]=(pre[i-1]+(ll)C(n,i)*(n-i*2))%P;
		else F[i]=pre[n-1-i];
		F[i]=(ll)F[i]*fac[n-i]%P;
	}
	for(int i=0;i<=n;++i) if(i&1) G[i]=fiv[i];else G[i]=P-fiv[i];
	G=F*G;
	for(int i=0;i<=n;++i) coe[i]=(ll)G[i]*pw[n-i]%P*fiv[n-i]%P;
	F.f.resize(n+2);
	G.f.resize(n+2);
	for(int i=0;i<=n+1;++i) F[i]=fiv[i+1];
	F=F.inv(n+2);
	for(int i=0,tt=1;i<=n+1;++i){
		G[i]=(ll)tt*fiv[i]%P;
		tt=(ll)tt*(m+1)%P;
	}
	G=F*G;
	for(int i=0;i<=n;++i) res=(res+(ll)coe[i]*(G[i+1]-F[i+1]+P)%P*fac[i])%P;
	res-=coe[0];
	if(res<0) res+=P;
	printf("%d\n",res);
	return 0;
}

标签:Minimizations,int,Many,sum,自然数,infin,题解,include
From: https://www.cnblogs.com/yyyyxh/p/18263819/many_isotonic_regression_countings

相关文章

  • [MdOI R5] Many Minimizations & [ARC164F] Many Increasing Problems 题解
    讲下一个思路比较自然的基于自然数幂和的\(O(n\logn)\)且复杂度与\(m\)几乎无关的做法。不难发现让我们计数的问题是保序回归\(L_1\)中一条链的情况。这个情况有一个简单的slope-trick做法:用堆维护斜率,每次push进去两个当前的数,然后pop出一个最大值。最终所有数的和......
  • C++题解(1) 信息学奥赛一本通 1003:对齐输出 洛谷 B2004:对齐输出 土豆编程 T1003:对
    【题目描述】读入三个整数,按每个整数占8个字符的宽度,右对齐输出它们,按照格式要求依次输出三个整数,之间以一个空格分开。【输入】只有一行,包含三个整数,整数之间以一个空格分开。【输出】只有一行,按照格式要求依次输出三个整数,之间以一个空格分开。【输入样例】......
  • 一些东西 题解
    ATBAB设\(f_{i,0/1}\)表示\(i\)子树DFS序奇/偶位置和的最大值,首先如果\(i\)所有孩子的子树大小都是偶数,那访问这些孩子的顺序就无所谓了,否则考虑以\(i\)的至少一个大小为奇数的孩子为分界,对所有大小为偶数的孩子\(v\),把\(f_{v,0}\)更大的\(v\)、\(f_{v,1}\)......
  • [题解]CF311B Cats Transport
    思路首先,对于每一只小猫刚好玩完就被饲养员接走的出发时间必定为\(t_i-sd_i\)。那么,我们令\(a_i=t_i-sd_i\)表示第\(i\)只小猫的最早出发时间。因此,对于第\(k\)时刻出发的饲养员能接到的小猫当且仅当满足\(a_i\leqk\)。然后,我们定义\(dp_{i,j}\)表示用\(i\)......
  • [题解]CF245H Queries for Number of Palindromes
    思路定义\(dp_{i,j}\)表示区间\([i,j]\)中回文串的数量。那么,不难得出状态转移方程\(dp_{i,j}=dp_{i-1}+f_{i,j}\)。(其中\(f_{i,j}\)表示左端点大于等于\(i\),右端点为\(j\)的回文串数量)由此,现在问题转变为了如何求\(f_{i,j}\)。如果我们在求出了\(f_{i+1,j}......
  • [题解]CF154B Colliders
    思路首先我们将两种操作分开讨论:Part1加入操作那么,我们可以用一个数组\(vis_i=0/1\)表示\(i\)是关闭/开启状态,\(p_i\)表示因数有\(i\)的数。如果$vis_x=1$,说明此机器在之前已经启动过了,输出Success。然后,对\(x\)分解质因数,将质因数全部塞进一个集合\(a\)......
  • [题解]AT_dp_w Intervals
    思路首先考虑较为普通的DP。定义\(dp_{i,j}\)表示在前\(i\)个位置中,最后一个1在\(j\)的最大分数,显然有:\[dp_{i,j}=\left\{\begin{matrix}\max_{k=1}^{i-1}\{dp_{i-1,k}\}+\sum_{l_k\leqj\wedger_k=i}{a_k}&(i=j)\\dp_{i-1,j}+\sum......
  • [题解]AT_arc138_a [ARC138A] Larger Score
    思路不难发现:对于每一个\(i(1\leqi\leqk)\),如果能在\((k+1)\simn\)中找到任何一个\(j\),满足\(a_j>a_i\)就算满足条件。进一步思考,为了使操作数最小,对于每一个\(1(1\leqi\leqk)\),都找一个在\((k+1)\simn\)中第一个大于\(a_i\)的数,便于它交换。那么......
  • [题解]AT_arc116_d [ARC116D] I Wanna Win The Game
    思路因为题目与二进制有关,考虑往二进制的方向思考。定义\(dp_{i,j}\)表示在所有的\(n\)个数中,当前在决策对于每一个数在二进制表示下的第\(i\)位是\(0\)还是\(1\),且和为\(j\)的方案数。因为异或需要满足对于所有\(a_i\)表示为二进制后每一位\(1\)的个数均为偶数......
  • [题解]AT_arc116_b [ARC116B] Products of Min-Max
    思路我们容易可以得到一个朴素的做法,首先对\(a\)数组排序,然后枚举最大值和最小值\(a_i,a_j\),那么对于中间的元素都有选与不选两种情况,得到答案:\[\sum_{i=1}^{n}(a_i\timesa_i+(\sum_{j=i+1}^{n}a_i\timesa_j\times2^{j-i-1}))\]然后对这个式子......