链接:https://codeforces.com/problemset/problem/1284/C
题意:定义一个framed segment,在区间[l,r]中,max值-min值 = r - l。求有1-n 组成的序列中,所有framed segment的个数%m
思路:组合数学推一个结论。例如假设1到n组成的序列中,求长度为k的framed segment,那么其一段序列的最大值 - 最小值 = k,例如n = 5,k = 3,这些framed segment 必定是 1 2 3 或者2 3 4 或者 3 4 5,可以观测到其长度为k的framed segment必定是连续的,可以把他们单独算一个整体,这样序列总体长度变为n - k + 1,内部长度为k,内部组合种类就是k!个,总体组合种类就是(n-k+1)!,长度为k的framed segment种类又是(123,234,345)n - k + 1种,所以长度为k的framed segment 最终答案就是(n-k+1)*(n-k+1)!*k!,预处理一下阶乘即可。
AC代码:
1 #include<iostream>
2 #include<cstdio>
3 #include<cstring>
4 #include<algorithm>
5 #include<vector>
6 #include<queue>
7 using namespace std;
8 typedef long long ll;
9 const int maxn = 2e5+5e4+5;
10 ll fac[maxn];
11 int main(){
12 ll n,m;
13 cin>>n>>m;
14 fac[1] = 1;
15 for(int i = 2;i<=n;i++){
16 fac[i] = (fac[i-1]*i)%m;
17 }
18 ll ans = 0;
19 for(int i = 1;i<=n;i++){
20 ans +=((n+1-i)*(fac[i])%m)*(fac[n+1-i])%m;
21 ans = ans%m;
22 }
23 // 1 2 3
24 cout<<ans%m;
25 return 0;
26 }
来源:https://www.cnblogs.com/AaronChang/p/12185455.html