CF1284C·New Year and Permutation

初见安~这里是传送门:Codeforces 1284C

Sol

这个题很有意思呀。就是给你一个n,求n的所有排列里区间左右端点的差等于区间内极差的区间的和。

其实手枚一下就可以发现,其实满足这个条件的区间内的数一定是连续的

所以我们从区间长度入手,对于每个长度的区间看对应了多少个排列满足要求

这就很简单了呀。我们枚举区间的极差i,考虑选差值为i的i+1个数有n-i种选法,区间内的顺序随意,整体看这i+1个数为一组,另外的n-i-1个数为n-i-1个组,这n-i个组的顺序同样随意。

所以就有:

\small ans =\sum_{i=0}^{n-1}(n-i)*(i+1)!(n-i)!

然后这个题就没了。

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
#define maxn 300005
using namespace std;
typedef long long ll;
int read() {
	int x = 0, f = 1, ch = getchar();
	while(!isdigit(ch)) {if(ch == '-') f = -1; ch = getchar();}
	while(isdigit(ch)) x = (x << 1) + (x << 3) + ch - '0', ch = getchar();
	return x * f;
}

int n, mod;
ll ans = 0, fac[maxn];
signed main() {
	n = read(), mod = read();
	fac[0] = 1;
	for(int i = 1; i <= 300000; i++) fac[i] = fac[i - 1] * i % mod;
	for(int i = 0; i < n; i++) ans = (ans + (n - i) * fac[i + 1] % mod * fac[n - i] % mod) % mod;
	printf("%lld\n", ans % mod);
	return 0;
}
 

迎评:)
——End——

发布了158 篇原创文章 · 获赞 23 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_43326267/article/details/103843503