C Optimal Strategy(数论,费马小定理)

原题链接

#include "iostream"
#include "cstring"
#include "algorithm"
using namespace std;
typedef long long ll;
const int N = 1e6 + 10; 
const int mod = 998244353;
int c[N];   //求某个数有几个 
ll f[N], inv[N];  //f求到哪个数的时候有几种组合 inv求 /f[i]对mod取模的值 
ll fact[N];

ll fast_pow(int x, int n){    //快速幂 
	ll t = 1;
	while(n){
		if(n & 1) t = t *  x % mod;
		x = 1ll*x * x % mod;
		n >>= 1;
	}
	return t;
}
void init(){        //预处理阶乘和阶乘的逆元 
	fact[0] = 1;
	for(int i = 1; i <= N; i++){
		fact[i] = fact[i - 1] * i % mod;
		inv[i] = fast_pow(fact[i], mod - 2);
	}
}

inline ll C(int n, int m){  //组合数  

	if(m == 0 || n == m || n == 0) return 1ll; 
	return 1ll* fact[n] * inv[m] % mod * inv[n - m] % mod;
	
}
int main(){
	ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
	memset(c, 0, sizeof(c));
	init();
	
	int n, x, ann;
	cin>>n;
	int ma = -1, mi = 1e6 + 10;
	for(int i = 0; i < n; i++){
		cin>>x;
		if(x > ma) ma = x;
		if(x < mi) mi = x;
		c[x] ++;
	}

	 ll cnt = 0;
	 f[mi] = fact[c[mi]];
	 cnt = c[mi];

	for(int i = mi + 1; i <= ma ; i++){		
		f[i] =  f[i - 1] * C(cnt + c[i]/ 2, c[i] / 2)% mod * fact[c[i]]%mod;
		cnt += c[i];

	}
	cout<<f[ma]<<endl;
	return 0;
}

这道题目就是一个贪心+动态规划的题目,和队友做了好久没做出来,后来看的大佬的题解,就是如果当前价值最大的是奇数的话,那就一定先拿最大的,如果是偶数的话,可以随便拿,但是一旦你前面的人拿了最大的,你就一定要也跟着拿最大的,否则就会输,所以就是两个相同价值的一定要成对出现,这样的话,我们从最小的开始(因为最小的话,拿的顺序其实是个全排列,这个既然都是最小了就不在意谁先拿谁后拿,反正都要拿走), 然后在这个的基础上,每增加一个就添加进一个n对(可以有单)的排列组合,以此类推,直到排列完最后一种数字。

值得注意的是,在我求组合数的时候运用了一个费马小定理来求,结论就是:

 a * a**(p - 2) % p = 1

a / b % p = a * b ** (p - 2) % p 

费马小定理 具体的可以看下这个大佬的博客!

好了,今天做的这套2021年济南站的ICPC真的是感觉,就是考高数啊,队友一个数院的小姐姐直接把看家本领都使出来了,果然还得是数院大佬啊,今天又学习了一个新的知识点,虽然说浪费的时间有点多吧。

  • 10
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小竹子14

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值