P7481 梦现时刻

P7481 梦现时刻

题意

给定 \(n,m\) ,保证 \(m\le n\),令 \(F(a,b)=\sum_{i=0}^{b}\binom{b}{i}\binom{n-i}{a}\)

\(\bigoplus_{a=1}^{m}\bigoplus_{b=1}^{m}(F(a,b) \bmod 998244353)\)

\(n \le 10^9, m \le 5000\)

思路

使用 \(O(m^2)\) 的时间复杂度求出所有 \(F(a,b)\)

因为状态数就有 \(O(m^2)\) 了,所以我们需要一些前缀和的或者递推的方式来计算。

\[F(a,b) = \sum_{i=0}^b \binom{b}{i} \binom{n-i}{a} \]

这一坨找不到什么可以继续推的线索或者怎么前缀和。

于是考虑递推。

\[\begin{aligned} F(a,b) & = \sum_{i=0} \binom{b}{i} \binom{n-i}{a}\text{(去掉边界,不影响结果)}\\ & = \sum_{i=0} (\binom{b-1}{i-1} + \binom{b-1}{i}) (\binom{n-i+1}{a+1} - \binom{n-i}{a+1})\\ & = F(a,b-1) - F(a+1,b) + 2F(a+1,b-1) \end{aligned} \]

其中比较特别的是 \(2F(a+1,b-1) = \sum_{i=0} \binom{b-1}{i-1} \binom{n-i+1}{a+1} + \binom{b-1}{i} \binom{n-i}{a+1}\)

注意 \(\binom{n}{m}\)\(m<0\) 的时候值为 \(0\)

\(a-1\) 替换 \(a\) 并移一下项得到(这样推起来舒服一点):

\[F(a,b) = F(a-1,b-1) - F(a-1,b) + 2F(a,b-1) \]

那么就做完了。

边界状态是 \(F(1,\cdot)\)\(F(\cdot,1)\)

code

应该不难写。

对不起!是我话说早了!我没想到我能打错这么多字!/ll

#include<bits/stdc++.h>
#define sf scanf
#define pf printf
#define rep(x,y,z) for(int x=y;x<=z;x++)
#define per(x,y,z) for(int x=y;x>=z;x--)
using namespace std;
typedef long long ll;
namespace wing_heart {
	constexpr int N=5e3+7, mod=998244353;
	int add(int a,int b) { return a+b>=mod ? a+b-mod : a+b; }
	void _add(int &a,int b) { a=add(a,b); }
	int mul(int a,int b) { return 1ll*a*b%mod; }
	void _mul(int &a,int b) { a=mul(a,b); }
	int ksm(int a,int b=mod-2) {
		int s=1;
		while(b) {
			if(b&1) _mul(s,a);
			_mul(a,a);
			b>>=1;
		}
		return s;
	}
	int ans;
	int n,m;
	int f[N][N];
	int inv[N];
    void main() {
		sf("%d%d",&n,&m);
		inv[1]=1;
		rep(i,2,m) inv[i]=mul(mod-mod/i,inv[mod%i]);
		int s1=1,s2=1;
		rep(a,1,m) {
			_mul(s1,n-a+1), _mul(s1,inv[a]);
			_mul(s2,n-a), _mul(s2,inv[a]);
			f[a][1]=add(s1,s2);
		}
		rep(b,2,m) {
			int sb=1;
			rep(i,0,b) {
				_add(f[1][b],mul(sb,n-i));
				_mul(sb,b-i), _mul(sb,inv[i+1]);
			}
		}
		rep(a,2,m) {
			rep(b,2,m) {
				f[a][b] = add(f[a-1][b-1],add(mod-f[a-1][b],mul(2,f[a][b-1])));
			}
		}
		rep(a,1,m) rep(b,1,m) ans^=f[a][b];
		pf("%d\n",ans);
    }
}
int main() {
    #ifdef LOCAL
    freopen("in.txt","r",stdin);
    freopen("my.out","w",stdout);
    #endif
    wing_heart :: main();
}
posted @ 2025-08-02 20:04  wing_heart  阅读(5)  评论(0)    收藏  举报