BZOJ5322:[JXOI2018]排序问题——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=5322
https://loj.ac/problem/2543 <-可以看数据,要没有这数据我死活调不出来。
https://www.luogu.org/problemnew/show/P4561
题面见上。
我们知道可重元素全排列=元素个数!/(每个元素个数!加和)。
所以一个很显然的贪心就是我们取元素使得每个元素的个数都尽可能小。
我们先离散化,然后二分出sum,表示l~r我每个元素都取至少sum个(“至少”表示原数列可能有l~r的元素且其个数可能超过了sum个)。
然后各种处理我们就能得到(每个元素个数!加和)了,怎么样,是不是很好想呢?
然而不好写。
注意二分上界为n+m原因就是l~r的元素可能出现在原序列且其个数为n。
#include<cmath>
#include<queue>
#include<cstdio>
#include<cctype>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=2e5+;
const int M=1e7+N;
const int p=;
inline int read(){
int X=,w=;char ch=;
while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
while(isdigit(ch))X=(X<<)+(X<<)+(ch^),ch=getchar();
return w?-X:X;
}
ll qpow(ll k,int n){
ll res=;
while(n){
if(n&)res=res*k%p;
k=k*k%p;n>>=;
}
return res;
}
int jc[M];
int a[N],b[N],num[N];
int n,m,l,r,t,cnt;
inline ll calc(int k){
ll sum=(ll)k*cnt;
for(int i=l;i<=r;i++){
if(num[i]<k)sum+=k-num[i];
}
return sum;
}
void work(){
for(int i=;i<=n;i++)num[a[i]]++;
int L=,R=n+m;
while(L<R){
int mid=(L+R+)>>;
if(calc(mid)<=m)L=mid;
else R=mid-;
}
ll ans=;
int last=m-calc(L);
for(int i=;i<=t;i++){
if(i<l||r<i)ans=ans*jc[num[i]]%p;
else{
if(num[i]>L)ans=ans*jc[num[i]]%p;
else if(last)last--,ans=ans*jc[L+]%p;
else ans=ans*jc[L]%p;
}
}
ans=ans*qpow(jc[L+],last)%p*qpow(jc[L],cnt-last)%p;
printf("%lld\n",qpow(ans,p-)*jc[n+m]%p);
}
void LSH(){
sort(b+,b+n+);
t=unique(b+,b+n+)-b-;
for(int i=;i<=t;i++)num[i]=;
for(int i=;i<=n;i++){
a[i]=lower_bound(b+,b+t+,a[i])-b;
}
cnt=r-l;
l=lower_bound(b+,b+t+,l)-b;
r=upper_bound(b+,b+t+,r)-b-;
cnt-=r-l;
}
int main(){
jc[]=;
for(int i=;i<M;i++)jc[i]=(ll)jc[i-]*i%p;
int T=read();
while(T--){
n=read(),m=read(),l=read(),r=read();
for(int i=;i<=n;i++)a[i]=b[i]=read();
LSH();
work();
}
return ;
}
+++++++++++++++++++++++++++++++++++++++++++
+本文作者:luyouqi233。 +
+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+
+++++++++++++++++++++++++++++++++++++++++++
BZOJ5322:[JXOI2018]排序问题——题解的更多相关文章
- BZOJ5322 [Jxoi2018]排序问题 【贪心】
题目链接 BZOJ5322 题解 意思就是使有序的排列尽量少 就是使相同的数尽量少 然后大力贪心即可 #include<algorithm> #include<iostream> ...
- BZOJ5322 JXOI2018排序问题
对于一个序列,重排后有序的概率显然是∏cnti!/n!,其中cnti为第i种数出现次数.要使概率最小,显然应该让各种数字尽量平均分配.剩下的是div2BC左右的大讨论. #include<ios ...
- BZOJ5322: [JXOI2018]排序问题
传送门 不难看出期望就是 \(\frac{(n+m)!}{\prod_{v=1}^{max}(cnt_v!)}\),\(cnt_v\) 表示 \(v\) 这个数出现的次数. 贪心就是直接把 \(m\) ...
- 【BZOJ5322】[JXOI2018]排序问题(模拟)
[BZOJ5322][JXOI2018]排序问题(模拟) 题面 BZOJ 洛谷 题解 这题就显得很呆. 显然就是每次找到\([l,r]\)中出现次数最小的那个数并且放一个. 然后随便模拟一下就好了Qw ...
- JXOI2018简要题解
JXOI2018简要题解 T1 排序问题 题意 九条可怜是一个热爱思考的女孩子. 九条可怜最近正在研究各种排序的性质,她发现了一种很有趣的排序方法: Gobo sort ! Gobo sort 的算法 ...
- 5322: [Jxoi2018]排序问题
5322: [Jxoi2018]排序问题 链接 分析: 每次选一个出现次数最小的. 代码: #include<cstdio> #include<algorithm> #incl ...
- 并不对劲的bzoj5322:loj2543:p4561:[JXOI2018]排序问题
题目大意 \(T\)(\(T\leq10^5\))组询问 每次给出\(n,m,l,r\),和\(n\)个数\(a_1,a_2,...,a_n\),要找出\(m\)个可重复的在区间\([l,r]\)的数 ...
- 洛谷P4561 [JXOI2018]排序问题(二分 期望)
题意 题目链接 Sol 首先一种方案的期望等于它一次排好的概率的倒数. 一次排好的概率是个数数题,他等于一次排好的方案除以总方案,也就是\(\frac{\prod cnt_{a_i}!}{(n+m)! ...
- [JXOI2018]排序问题
嘟嘟嘟 这是今天做的第二道九条可怜的题,现在对他的题的印象是:表面清真可做,实则毒瘤坑人. 首先要感谢吉司机,我期望学的特烂,好在样例直接告诉我们期望怎么求了. 令\(b_i\)表示第\(i\)个不同 ...
随机推荐
- 转:Docker创建centos的LNMP镜像
转自:http://www.vckai.com/p/29 1. 安装docker 这个就不说了,不会的可以看下我之前的文章<Docker介绍及安装>. 1)启动docker # serv ...
- vim中project多标签和多窗口的使用
1.打开多个窗口 打开多个窗口的命令以下几个: 横向切割窗口 :new+窗口名(保存后就是文件名) :split+窗口名,也可以简写为:sp+窗口名 纵向切割窗口名 :vsplit+窗口名,也可以简写 ...
- protected修饰符详解
protected这个修饰符,各大参考书都会这样说:访问权限为类内,包内和子类,因此在父类中定义的方法和成员变量如果为protected修饰的,是可以在不同包中的子类进行访问的,示例代码如下: pac ...
- Ubuntu 14.04 登录 界面添加 root账号
1打开终端输入:sudo gedit /usr/share/lightdm/lightdm.conf.d/50-ubuntu.conf 2在弹出的编辑框里加入:greeter-show-manual- ...
- lesson 14 A noble gangster
lesson 14 A noble gangster there was a ++time++ 时期 times 时期/年代 in times of peace a sum of + money 一笔 ...
- 给大家推荐:五个Python小项目,Github上的人气很高的
1.深度学习框架 Pytorch https://github.com/pytorch/pytorch PyTorch 是一个 Torch7 团队开源的 Python 优先的深度学习框架,提供两个高级 ...
- C 计算身高
#include <stdio.h> int main(int argc, char **argv) { //输出一句话printf("请分别输入身高的英尺和英寸," ...
- Oracle启动与关闭数据库实例
Oracle数据库启动实例分为3个步骤: 启动实例 加载数据库 打开数据库 通用模式: STARTUP [ nomount | mount | open | force ] [resetrict] ...
- laravel 的DB::raw() 语法使用
z之前在项目中遇到一个问题,复杂的sql查询,用laravel的查询构造器,非常的不方便,各种查询条件拼接一长串拼得脑瓜疼:然后想使用原生的sql语句来查询,然后又使用不了laravel的pagina ...
- 创建一个socket服务实时统计在线人数
主要是两个文件,一个是后端文件,一个是前端文件: 后端文件:有人登录了,就通知所有的正在访问的页面,把总人数+1:反之-1: 前端文件:有人登录了,通知后端,页面关闭了,通知后端,同时接收后端派发来的 ...