Codeforces889C. Maximum Element

$n \leq 2000000$的排列,问有多少满足:存在个$i$,使得$p_i \neq n$,且$p_j

排列题还是比较菜。。

这次的切入点依然是排列题的经典套路--考虑将$n$加入$n-1$的合法排列,从而建立递推关系。

先从答案要求入手,假如把$n$插进位置$i$,那么$i$之前的序列必须已经合法,否则要么接下来一个数是$n$,后面$K$个数一定$

注意这里通过大小关系把$n$变成更小的东西。

现在试着求$D(i)$。首先$i<=K$时$D(i)=0$这实际上排除了一重条件$p_i \neq n$,因为此时造成$p_j

 1 //#include
 2 #include
 3 #include
 4 #include
 5 //#include
 6 //#include
 7 //#include
 8 #include
 9 #include
10 using namespace std;
11 
12 int n,K;
13 #define maxn 2000011
14 const int mod=1e9+7;
15 int fac[maxn],inv[maxn];
16 
17 int powmod(int a,int b)
18 {
19     int ans=1;
20     while (b)
21     {
22         if (b&1) ans=1ll*a*ans%mod;
23         a=1ll*a*a%mod; b>>=1;
24     }
25     return ans;
26 }
27 
28 int sum[maxn],f[maxn];
29 int main()
30 {
31     scanf("%d%d",&n,&K);
32     fac[0]=1; for (int i=1;i<=n;i++) fac[i]=fac[i-1]*1ll*i%mod;
33     inv[n]=powmod(fac[n],mod-2); for (int i=n;i>=1;i--) inv[i-1]=1ll*inv[i]*i%mod;
34     for (int i=1;i<=K;i++) f[i]=sum[i]=0;
35     for (int i=K+1;i<=n;i++)
36     {
37         f[i]=(1ll*(i-K-1)*fac[i-2]%mod+1ll*fac[i-2]*(sum[i-1]+mod-sum[i-K-1])%mod)%mod;
38         sum[i]=(sum[i-1]+1ll*f[i]*inv[i-1])%mod;
39     }
40     int ans=0;
41     for (int i=1;i<=n;i++) ans=(ans+1ll*(sum[i]-sum[i-1]+mod)*fac[n-1])%mod;
42     printf("%d\n",ans);
43     return 0;
44 }
View Code

转载于:https://www.cnblogs.com/Blue233333/p/8576380.html

你可能感兴趣的:(Codeforces889C. Maximum Element)