蒟蒻君的刷题日记Day13:P8106 [Cnoi2021]数学练习

解题思路

这么水的题竟然没有大佬交题解…

首先, ∵ ∣ S ∣ ∉ S , ∣ T ∣ ∉ T ∴ ∣ S ∣ ∈ T , ∣ T ∣ ∈ S \because |S| \notin S, |T| \notin T \therefore |S| \in T, |T| \in S S/S,T/TST,TS

确定了这两个值在哪边,其余 n − 2 n-2 n2 个排在哪边都无所谓了,有 2 n − 2 2^{n-2} 2n2 种方法。

注意一个值不能同时在 S S S T T T 中,则 ∣ S ∣ ≠ ∣ T ∣ |S| \ne |T| S=T。这种情况只会在 n n n 为偶数时发生,所以此时的总方案数应该减去从 n − 2 n-2 n2 个数中选出一半放在 S S S 中的数量,即 C n − 2 ( n − 2 ) / 2 C_{n-2}^{(n-2)/2} Cn2(n2)/2

最后注意的是 n = 1 n=1 n=1 时需要特判,因为根本没有 ∣ S ∣ |S| S ∣ T ∣ |T| T 两个值。

代码实现

组合数取模用了一点 L u c a s Lucas Lucas

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int P = 998244353;
int qpow(int x, int y) {
	int res = 1;
	while (y) {
		if (y & 1) {
   			(res *= x) %= P;
		}
		(x *= x) %= P;
		y >>= 1;
	}
	return res;
}
int C(int n, int m) {
	int a = 1, b = 1;
	for (int i = 1; i <= m; ++i) {
		(a *= i) %= P;
		(b *= n - i + 1) %= P;
	}
	return b * qpow(a, P - 2) % P;
}
int Lucas(int n, int m) {
    return !m ? 1 : C(n % P, m % P) * Lucas(n / P, m / P) % P;
}
signed main() {
	ios :: sync_with_stdio(0);
    int n;
    cin >> n;
    if (n == 1) {
		cout << 0 << '\n';
		return 0;
	}
    int res = qpow(2, n - 2);
    if (!(n & 1)) {
    	(res -= Lucas(n - 2, n - 2 >> 1) - P) %= P;
	}
	cout << res << '\n';
	return 0;
}

Good Good 贺题,Day Day Up!!

  • 6
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蒟蒻一枚

谢谢鸭~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值