推式子 /kk

P8367 [LNOI2022] 盒

题目
首先可以发现每次操作就是在前缀和数组的某一个上 +- 1 1 1。所以就转换成 ∑ i = 1 n ∣ p r e a [ i ] − p r e b [ i ] ∣ × w [ i ] \sum_{i=1}^n |pre_a[i]-pre_b[i]|\times w[i] i=1nprea[i]preb[i]×w[i]
所以最终的答案就是这个(后面的组合数表示 i i i 前面填的方案和 i i i 后面填的方案) ∑ i = 1 n ∑ j = 0 m w [ i ] × ∣ j − p r e [ i ] ∣ ( i + j − 1 i − 1 ) ( n − i + m − j − 1 n − i − 1 ) \sum_{i=1}^n\sum_{j=0}^mw[i]\times|j-pre[i]|\binom{i+j-1}{i-1}\binom{n-i+m-j-1}{n-i-1} i=1nj=0mw[i]×jpre[i](i1i+j1)(ni1ni+mj1)
因为绝对值很难处理,所以将绝对值符号拆开对于 j ≤ p r e [ i ] j\le pre[i] jpre[i] 的情况如下, j > p r e [ i ] j>pre[i] j>pre[i] 的情况同理。
∑ j = 0 p r e [ i ] p r e [ i ] × ( i + j − 1 i − 1 ) ( n − i + m − j − 1 n − i − 1 ) − j × ( i + j − 1 i − 1 ) ( n − i + m − j − 1 n − i − 1 ) \sum_{j=0}^{pre[i]}pre[i]\times\binom{i+j-1}{i-1}\binom{n-i+m-j-1}{n-i-1}-j\times\binom{i+j-1}{i-1}\binom{n-i+m-j-1}{n-i-1} j=0pre[i]pre[i]×(i1i+j1)(ni1ni+mj1)j×(i1i+j1)(ni1ni+mj1)
s 1 ( n , m , i , p r e [ i ] ) = ∑ j = 0 p r e [ i ] ( i + j − 1 i − 1 ) ( n − i + m − j − 1 n − i − 1 ) s_1(n,m,i,pre[i])=\sum_{j=0}^{pre[i]}\binom{i+j-1}{i-1}\binom{n-i+m-j-1}{n-i-1} s1(n,m,i,pre[i])=j=0pre[i](i1i+j1)(ni1ni+mj1)
s 2 ( n , m , i , p r e [ i ] ) = ∑ j = 0 p r e [ i ] j × ( i + j − 1 i − 1 ) ( n − i + m − j − 1 n − i − 1 ) s_2(n,m,i,pre[i])=\sum_{j=0}^{pre[i]}j\times\binom{i+j-1}{i-1}\binom{n-i+m-j-1}{n-i-1} s2(n,m,i,pre[i])=j=0pre[i]j×(i1i+j1)(ni1ni+mj1)
∴ a n s = ∑ i = 1 n ( s 1 ( n , m , i , p r e [ i ] ) × p r e [ i ] + s 2 ( n , m , i , p r e [ i ] ) ) \therefore ans=\sum_{i=1}^n(s_1(n,m,i,pre[i])\times pre[i]+s_2(n,m,i,pre[i])) ans=i=1n(s1(n,m,i,pre[i])×pre[i]+s2(n,m,i,pre[i]))

  • 首先考虑 s 1 s_1 s1 如何计算。
    s 1 ( n , m , x , y ) = ∑ j = 0 y ( x + j − 1 x − 1 ) ( n − x + m − j − 1 n − x − 1 ) s_1(n,m,x,y)=\sum_{j=0}^y \binom{x+j-1}{x-1}\binom{n-x+m-j-1}{n-x-1} s1(n,m,x,y)=j=0y(x1x+j1)(nx1nx+mj1)
    考虑像莫队一样处理,容易知道 ( x , y ) → ( x , y + 1 ) (x,y)\rightarrow (x,y+1) (x,y)(x,y+1) 是容易的。
    然后考虑如何从 ( x , y ) → ( x + 1 , y ) (x,y)\rightarrow(x+1,y) (x,y)(x+1,y)
    重新考虑 s 1 s_1 s1 的组合意义,就是有 m m m 个小球, n n n 个盒子,每个盒子可以放非负个小球,并且第 [ p r e [ i ] + 1 , m ] [pre[i]+1,m] [pre[i]+1,m] 个小球必须放在 [ i + 1 , n ] [i+1,n] [i+1,n] 的盒子里的方案数。
    所以枚举第 p r e [ i ] + 1 pre[i]+1 pre[i]+1 个小球的位置,然后 [ 1 , p r e [ i ] ] [1,pre[i]] [1,pre[i]] 的球放在 [ 1 , j ] [1,j] [1,j] 的盒子中; [ p r e [ i ] + 2 , m ] [pre[i]+2,m] [pre[i]+2,m] 的球放在 [ j , n ] [j,n] [j,n] 的盒子中。
    方案数也就是 ∑ j = i + 1 n ( j + p r e [ i ] − 1 j − 1 ) ( n − j + m − p r e [ i ] − 1 n − j ) \sum_{j=i+1}^n \binom{j+pre[i]-1}{j-1}\binom{n-j+m-pre[i]-1}{n-j} j=i+1n(j1j+pre[i]1)(njnj+mpre[i]1)
  • 然后考虑 s 2 s_2 s2 如何计算。
    可以发现, j × ( i + j − 1 i − 1 ) = j × ( i + j − 1 j ) = i × ( i + j − 1 i ) j\times\binom{i+j-1}{i-1}=j\times\binom{i+j-1}{j}=i\times\binom{i+j-1}{i} j×(i1i+j1)=j×(ji+j1)=i×(ii+j1)
    s 2 ( n , m , i , p r e [ i ] ) = ∑ j = 0 p r e [ i ] j × ( i + j − 1 i − 1 ) ( n − i + m − j − 1 n − i − 1 ) s_2(n,m,i,pre[i])=\sum_{j=0}^{pre[i]}j\times\binom{i+j-1}{i-1}\binom{n-i+m-j-1}{n-i-1} s2(n,m,i,pre[i])=j=0pre[i]j×(i1i+j1)(ni1ni+mj1)
    = i × ∑ j = 0 p r e [ i ] ( i + j − 1 i ) ( n − i + m − j − 1 n − i − 1 ) =i\times\sum_{j=0}^{pre[i]}\binom{i+j-1}{i}\binom{n-i+m-j-1}{n-i-1} =i×j=0pre[i](ii+j1)(ni1ni+mj1)
    注意到这个式子在 j = 0 j=0 j=0 时前一个组合数的 i + j − 1 < i i+j-1<i i+j1<i 也就无意义的,所以 j j j 整体平移 1 1 1
    = i × ∑ j = 0 p r e [ i ] − 1 ( i + j i ) ( n − i + m − j − 2 n − i − 1 ) =i\times\sum_{j=0}^{pre[i]-1}\binom{i+j}{i}\binom{n-i+m-j-2}{n-i-1} =i×j=0pre[i]1(ii+j)(ni1ni+mj2)
    ∴ s 2 ( n , m , i , p r e [ i ] ) = i × s 1 ( n + 1 , m − 1 , i + 1 , p r e [ i ] − 1 ) \therefore s_2(n,m,i,pre[i])=i\times s_1(n+1,m-1,i+1,pre[i]-1) s2(n,m,i,pre[i])=i×s1(n+1,m1,i+1,pre[i]1)
    另外对于之前分类讨论时同理的 j > p r e [ i ] j>pre[i] j>pre[i] 在这里丢一下 s 1 s_1 s1 的两种式子:
    s 1 ( n , m , i , p r e [ i ] ) = ∑ j = p r e i + 1 m ( i + j − 1 i − 1 ) ( n − i − 1 + m − p r e i n − i − 1 ) s_1(n,m,i,pre[i])=\sum_{j=pre_i+1}^m \binom{i+j-1}{i-1} \binom{n-i-1+m-pre_i}{n-i-1} s1(n,m,i,pre[i])=j=prei+1m(i1i+j1)(ni1ni1+mprei)
    s 1 ( n , m , i , p r e [ i ] ) = ∑ j = 1 i ( j − 1 + p r e i + 1 j − 1 ) ( n − j + m − p r e i − 1 n − j ) s_1(n,m,i,pre[i])=\sum_{j=1}^i \binom{j-1+pre_i+1}{j-1} \binom{n-j+m-pre_i-1}{n-j} s1(n,m,i,pre[i])=j=1i(j1j1+prei+1)(njnj+mprei1)

主要参考了 Kubic 的题解

P5400 [CTS2019] 随机立方体

题目

P10004 [集训队互测 2023] Permutation Counting 2

题目
因为有 i i i 个上升的位置,所以有 n − i n-i ni 个连续上升的段
首先容斥,钦定原序列有 i i i 个上升段,逆序列有 j 个上升段
假设值为 f [ i ] [ j ] f[i][j] f[i][j] a n s [ i ] [ j ] = ∑ k = i n − 1 ∑ l = j n − 1 ( − 1 ) ( k + l − i − j ) × C ( k , i ) × C ( l , j ) × f [ i ] [ j ] ans[i][j] = \sum_{k=i}^{n-1}\sum_{l=j}^{n-1} (-1)^(k+l-i-j)\times C(k,i)\times C(l,j)\times f[i][j] ans[i][j]=k=in1l=jn1(1)(k+lij)×C(k,i)×C(l,j)×f[i][j]
将逆序列中的连续段的下标往原序列中的连续段里填,可以注意到在原序列的每个连续段中所填的数始终是一个前缀 ?
所以 a [ i ] [ j ] a[i][j] a[i][j] 表示原序列的第 i i i 个连续段和逆序列的第 j j j 个连续段的交集大小
a [ i ] [ j ] a[i][j] a[i][j] 和原序列是一一对应的 ?
并且可以注意到 a [ i ] [ j ] a[i][j] a[i][j] 区别于任意的一个矩阵的限制条件是

  1. x x x y y y 列,和为 n n n
  2. 矩阵内每个数都是非负整数
  3. 不存在一行或一列和为 0 0 0
    对于第 3 个限制,再进行一个二维的二项式反演, g [ i ] [ j ] g[i][j] g[i][j] 表示钦定有 i i i j j j 列和为 0 0 0 h [ i ] [ j ] h[i][j] h[i][j] 表示恰好 i i i j j j 列和为 0 0 0
    g [ i ] [ j ] = C ( x , i ) × C ( y , j ) × C ( n + ( x − i ) × ( y − j ) − 1 , ( x − i ) × ( y − j ) − 1 ) g[i][j] = C(x,i)\times C(y,j)\times C(n+(x-i)\times(y-j)-1,(x-i)\times(y-j)-1) g[i][j]=C(x,i)×C(y,j)×C(n+(xi)×(yj)1,(xi)×(yj)1)
    g [ i ] [ j ] = ∑ a = i x ∑ b = j y C ( a , i ) × C ( b , j ) × h [ a ] [ b ] g[i][j] = \sum_{a=i}^x \sum_{b=j}^y C(a,i)\times C(b,j)\times h[a][b] g[i][j]=a=ixb=jyC(a,i)×C(b,j)×h[a][b]
    h [ i ] [ j ] = ∑ a = i x ∑ b = j y ( − 1 ) a + b − i − j C ( a , i ) × C ( b , j ) × g [ a ] [ b ] h[i][j] = \sum_{a=i}^x \sum_{b=j}^y (-1)^{a+b-i-j} C(a,i)\times C(b,j)\times g[a][b] h[i][j]=a=ixb=jy(1)a+bijC(a,i)×C(b,j)×g[a][b]
    f [ x ] [ y ] = h [ 0 ] [ 0 ] f[x][y] = h[0][0] f[x][y]=h[0][0]
    上面的时间复杂度是 O ( n 4 ) O(n^4) O(n4)
    但注意到二项式反演的两维互不影响,所以分开做,是 O ( n 3 ) O(n^3) O(n3) 的。

参考了 Nesraychan QOJ 上的代码的取模优化。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<map>
#include<queue>
#define ull unsigned long long
using namespace std;
const int N=505;
int n,mod;
ull qwq;
int fac[N*N],inv[N*N],ifac[N*N],tmp[N],g[N][N],f[N][N],ans[N][N];
inline int read()
{
	int s=0,t=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')t=-1;ch=getchar();}
	while(ch>='0'&&ch<='9') s=(s<<1)+(s<<3)+(ch^48),ch=getchar();
	return s*t;
}
inline int fastmod(ull a)
{
	ull awa=((__uint128_t)a*qwq)>>64;
	int rest=a-awa*mod;
	return (rest<mod?rest:rest-mod);
}
inline int add(int a,int b){return (a+b>=mod?a+b-mod:a+b);}
inline int del(int a,int b){return (a-b<0?a-b+mod:a-b);}
inline int mul(int a,int b){return (1ull*a*b<mod?a*b:fastmod(1ull*a*b));}
inline void init(int n)
{
	fac[0]=inv[0]=ifac[0]=fac[1]=inv[1]=ifac[1]=1;
	for(int i=2;i<=n;++i)
	{
		fac[i]=mul(fac[i-1],i);
		inv[i]=mul((mod-mod/i),inv[mod%i]);
		ifac[i]=mul(ifac[i-1],inv[i]);
	}
	return;
}
inline int C(int n,int m)
{
	if(n<0||m<0||n-m<0) return 0;
	return mul(mul(fac[n],ifac[m]),ifac[n-m]);
}
int main()
{
	n=read();
	mod=read();
	qwq=((__uint128_t)1<<64)/mod;
	init(n*(n+5));
	for(int y=1;y<=n;++y)
	{
		for(int i=0;i<=n;++i)
		{
			tmp[i]=0;
			for(int j=0;j<=y;++j)
			{
				int sig=y-j;
				if(sig&1) tmp[i]=del(tmp[i],mul(C(y,j),C(n+i*j-1,i*j-1)));
				else tmp[i]=add(tmp[i],mul(C(y,j),C(n+i*j-1,i*j-1)));
			}
		}
		for(int x=1;x<=n;++x)
		{
			int val=0;
			for(int i=0;i<=x;++i)
			{
				int sig=x-i;
				if(sig&1) val=del(val,mul(C(x,i),tmp[i]));
				else val=add(val,mul(C(x,i),tmp[i]));
			}
			f[n-y][n-x]=val;
		}
	}
	for(int y=0;y<=n-1;++y)
	{
		for(int i=0;i<=n-1;++i)
		{
			tmp[i]=0;
			for(int j=y;j<=n-1;++j)
			{
				int sig=j-y;
				if(sig&1) tmp[i]=del(tmp[i],mul(C(j,y),f[j][i]));
				else tmp[i]=add(tmp[i],mul(C(j,y),f[j][i]));
			}
		}
		for(int x=0;x<=n-1;++x)
			for(int i=x;i<=n-1;++i)
			{
				int sig=i-x;
				if(sig&1) ans[y][x]=del(ans[y][x],mul(C(i,x),tmp[i]));
				else ans[y][x]=add(ans[y][x],mul(C(i,x),tmp[i]));
			}
	}
	for(int i=0;i<=n-1;++i)
		for(int j=0;j<=n-1;++j)
			printf("%d%c",ans[j][i]," \n"[j==n-1]);
	return 0;
}
  • 22
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值