题面在这里
\(f_{i,j}\):长度为i,以j结尾的非降序列个数 \[
f_{i,j}=\sum_{k\lt i}^{a_k\le a_i} f_{i-1,k}
\] 直接用树状数组优化到\(O(n^2\log n)\)
于是得到\(g_i\):长度为i的非降序列个数
答案就是 \[
\sum_{i=1}^n g_i(n-i)!-g_{i+1}(i+1)(n-i-1)!
\] 如何理解?
直接\(\sum g_i(n-i)!\)肯定是不对的,因为有些已经变成非降序列但没有停止删除
但是不合法方案一定是由\(g_{i+1}\)来的,枚举删去哪个数,得到对应方案
示例程序:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 
 | #include<cstdio>#include<cstring>
 #include<algorithm>
 #define cl(x,y) memset(x,y,sizeof(x))
 using namespace std;
 typedef long long ll;
 
 const int maxn=2005,MOD=1e9+7;
 int n,m,a[maxn],b[maxn],f[maxn][maxn],g[maxn];
 ll fac[maxn];
 int BIT[maxn];
 #define lowbit(x) ((x)&-(x))
 inline void ist(int x,int w){
 for (int i=x;i<=m;i+=lowbit(i)) (BIT[i]+=w)%=MOD;
 }
 inline int qry(int x){
 int res=0;
 for (int i=x;i;i-=lowbit(i)) (res+=BIT[i])%=MOD;
 return res;
 }
 int main(){
 scanf("%d",&n);
 for (int i=1;i<=n;i++) scanf("%d",&a[i]),b[i]=a[i];
 sort(b+1,b+1+n); m=unique(b+1,b+1+n)-1-b;
 for (int i=1;i<=n;i++) a[i]=lower_bound(b+1,b+1+m,a[i])-b;
 for (int i=1;i<=n;i++) f[1][i]=1;
 for (int i=2;i<=n;i++){
 cl(BIT,0);
 for (int j=1;j<=n;j++){
 f[i][j]=qry(a[j]);
 ist(a[j],f[i-1][j]);
 }
 }
 for (int i=1;i<=n;i++)
 for (int j=1;j<=n;j++)
 (g[i]+=f[i][j])%=MOD;
 fac[0]=1;
 for (int i=1;i<=n;i++) fac[i]=(fac[i-1]*i)%MOD;
 ll ans=0;
 for (int i=1;i<=n;i++)
 (ans+=g[i]*fac[n-i]%MOD-g[i+1]*fac[n-i-1]%MOD*(i+1)%MOD)%=MOD;
 printf("%lld",(ans+MOD)%MOD);
 return 0;
 }
 
 |