码迷,mamicode.com
首页 > 其他好文 > 详细

Codeforces889C. Maximum Element

时间:2018-03-15 22:17:15      阅读:237      评论:0      收藏:0      [点我收藏+]

标签:ace   比较   com   opened   return   close   mod   view   存在   

$n \leq 2000000$的排列,问有多少满足:存在个$i$,使得$p_i \neq n$,且$p_j<p_i,j \in [i+1,i+K]$,$K \leq 2000000$是给定常数。膜$1e9+7$。

排列题还是比较菜。。

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

先从答案要求入手,假如把$n$插进位置$i$,那么$i$之前的序列必须已经不合法,否则要么接下来一个数是$n$,后面$K$个数一定$<n$,就gg。也就是说,$n$之前的数字的大小关系已经确定了。确定大小关系的情况可以开始递推:$D(n)$表示$n$在位置$n$时,剩下$n-1$个数乱排时的不合法排列数——$n$在位置$i$时,前$i$个数一旦确定,他们的大小关系必须如同$D(n)$的方案,然后其他的数乱排列。因此最终答案为$\sum_{i=1}^{n}D(i)\frac{(n-1)!}{(i-1)!}$。搞定。

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

现在试着求$D(n)$。首先$n<=K$时$D(n)=0$这实际上排除了一重条件$p_i \neq n$,因为此时造成$p_j<p_i,j \in [i+1,i+K]$的只有非$n$的数。好那就来看看剩下最大的$n-1$。当$n-1$放在前$n-K-1$个位置时,它就是符合条件的$i$。当它放在$n-K$往后的位置时,又来!此时$n-1$后边是不可能有非法$i$了,但前面一定有,大小关系又是$D$!于是有$D(n)=(n-K-1)(n-2)!+\sum_{i=n-K}^{n-1}D(i)*\frac{(n-2)!}{(i-1)!}$,把$(n-2)!$提到前面,记个前缀和即可。

技术分享图片
 1 //#include<iostream>
 2 #include<cstring>
 3 #include<cstdlib>
 4 #include<cstdio>
 5 //#include<queue>
 6 //#include<time.h>
 7 //#include<complex>
 8 #include<algorithm>
 9 #include<stdlib.h>
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

 

Codeforces889C. Maximum Element

标签:ace   比较   com   opened   return   close   mod   view   存在   

原文地址:https://www.cnblogs.com/Blue233333/p/8576380.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!