我计划预习五个小时离散,然后hmc补了这道他自认为非常的裸并且很傻逼自己可以一眼秒的简单题,然后给我讲了讲,然后我失去了一整晚的生命迹象。

首先我们可以发现一个神奇的现象,啊,先排个序,然后我们会发现,一个数 是 合法的(指左边的全部小于等于它,右边的全部大于等于它),当且仅当它在自己拍完序的位置上。

先不考虑很多相同的。 所以我们可以怎么做呢。从左到右枚举每个 合法的数,然后从左到右 枚举 起点。这样考虑,用dp[n]表示 从 1到 n ,n是合法的数的时候的方案数,ans[n]表示从1到n , 不合法的方案数。 c[n] 表示从 1 到 n 的 排列总数。 显然 。。。好难描述。

唔,显然我们这样枚举会有很多重复的情况对吧。  艹,我先把hmc讲给我我听懂了的复述一下,一个数是 合法的 方案数, 就是 它左边的数xjb排和右边的数xjb排然后乘起来吧。

好啊其实我觉得他就说了这一局有用的。

所以我们可以采用 总排列数-所有合法情况。然后合法情况会有重复的,这个时候就要进行类似容斥的操作对不对。ex: 1,2  1,2;被计算了两次

所以我们可以 计算出 左边 不合法的 方案数。 用不合法的 再去乘 右边合法的 就一定不会和 之前的重复了,因为之前计算的是左边的合法的。

那么首先我们要知道每个子区间的排列总数,可以边计算顺便枚举,也可以先预处理出来。我比较傻逼混在一起就神志不清了就预处理出来的。

然后我们用 ans[i] 表示 到i 为止 的答案, dp[i]表示到 i为止 合法的 方案数。

第一层枚举 现在的区间 ,[1,i]; 第二层枚举 子区间, j  from 1 to i  ;

然后维护就好了。

emmm你要是不知道费马小定理的话,,,我也木有办法  也可以用递推式求对不对。

 #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod = 1e9+;
const int N = ;
ll inv[N];
ll n,c[N][N],a[N];
ll qpow(ll a,ll x){
ll res = ;
while (x){
if(x&)
res=res*a%mod;
a=a*a%mod;
x>>=;
}
return res;
}
void init(){
inv[]=;
for(int i=;i<=;i++)
inv[i]=qpow(i,mod-);
}
void slove(int n){
map<int,int> mp;
for(int i=;i<=n;i++){
c[i][i-]=;
mp.clear();
for(int j=i;j<=n;j++){
c[i][j]=c[i][j-]*(j-i+)%mod*inv[++mp[a[j]]]%mod;
}
c[i+][i]=;
}
}
ll dp[N],ans[N];
int main(){
init();
ios::sync_with_stdio(false);
cin>>n;
for(int i=;i<=n;i++){
cin>>a[i];
}
sort(a+,a++n);
slove(n);
ans[]=;
for(int i=;i<=n;i++){
for(int j=;j<=i;j++){
dp[i]=(dp[i]+ans[j-]*c[j+][i])%mod;
}
//cout<<dp[i]<<' ';
ans[i]=(c[][i]-dp[i]+mod)%mod;
//cout<<ans[i]<<endl;
}
cout<<ans[n]<<endl;
}

gym102007 E的更多相关文章

随机推荐

  1. 让你提升命令行效率的 Bash 快捷键

    生活在 Bash shell 中,熟记以下快捷键,将极大的提高你的命令行操作效率. 编辑命令 Ctrl + a :移到命令行首 Ctrl + e :移到命令行尾 Ctrl + f :按字符前移(右向) ...

  2. 03、操作RDD(transformation和action案例实战)

    1.transformation和action介绍 Spark支持两种RDD操作:transformation和action.transformation操作会针对已有的RDD创建一个新的RDD:而a ...

  3. windows下查看特定端口被什么程序占用

    我电脑上因为命令: netstat -ano 列出的太多了,所以不好看. 以下是其他方式: 查看8088端口占用情况: 开始---->运行---->cmd,或者是window+R组合键,调 ...

  4. Mybatis 级联查询时只查出了一条数据

    造成这个问题的原因是: 主表和明细表的id字段名相同造成的. 问题的关键在于resultMap中如果不定义类似主键之类的能够区分每一条结果集的字段的话,会引起后面一条数据覆盖前面一条数据的现象.

  5. Nuxt.js部署应用的方式

    Nuxt.js 提供了两种发布部署应用的方式:服务端渲染应用部署 和 静态应用部署. 静态应用部署就不说了,主要说说服务端渲染应用部署. 官方部署方式 关于服务端渲染应用部署,官方文档是这么写的: 部 ...

  6. 判断回文字符串、回文链表、回文数(python实现)

    所谓回文字符串,就是正读和反读都一样的字符串,比如"level"或者"noon"等等就是回文串.即是对称结构 判断回文字符串 方法一: def is_palin ...

  7. [MySQL Reference Manual]17 Group Replication

    17 Group Replication 17 Group Replication 17.1 Group Replication后台 17.1.1 Replication技术 17.1.1.1 主从复 ...

  8. 【转】Python3使用Django2.x的settings文件详解

    # -*- coding:utf8 -*- import os # 项目路径 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__ ...

  9. Linux常用指令笔记

    目标:统计当前目录下java文件的个数 指令:`ls -R ./ | grep .java$ | wc -l` 原理:`ls -R ./`列出当前文件夹下的所有FILE,包括目录以及文件;`grep ...

  10. 【GMT43智能液晶模块】例程十三:FATFS实验——文件操作

    实验原理: STM32F429上带有SDIO控制器,GMT43液晶模块上将SDIO连接到TF卡座.本实验 将Micro SD卡插入TF卡座上即可.通过FATFS创建test.txt文件,并且写入数据0 ...