题意

题目链接

Sol

首先一种方案的期望等于它一次排好的概率的倒数。

一次排好的概率是个数数题,他等于一次排好的方案除以总方案,也就是\(\frac{\prod cnt_{a_i}!}{(n+m)!}\)。因为最终的序列是一定的,两个序列不同当且仅当权值相同的数排列方式不同。

他的期望为\(\frac{(n+m)!}{\prod cnt_i!}\),我们希望这玩意儿尽量大,也就是下面的尽量小

显然对于每个\(cnt\)来说,最大值越小越好,可以直接二分,然后check一下是否可行。

具体的贪心策略是每次先填出现次数最少的。

复杂度\(O(nlogn)\)

#include<bits/stdc++.h>
#define Fin(x) freopen(#x".in", "r", stdin);
#define int long long
using namespace std;
const int MAXN = 2e7 + 10, mod = 998244353;
template<typename A, typename B> inline bool chmax(A &x, B y) {return x < y ? x = y, 1 : 0;}
template<typename A, typename B> inline bool chmin(A &x, B y) {return x > y ? x = y, 1 : 0;}
template<typename A, typename B> inline A mul(A x, B y) {return 1ll * x * y % mod;}
template<typename A, typename B> inline void add2(A &x, B y) {x = x + y >= mod ? x + y - mod : x + y;}
inline int read() {
char c = getchar(); int x = 0, f = 1;
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
int N, M, fac[MAXN], L, R, a[MAXN], date[MAXN], num, cnt[MAXN], pl, pr, l, r;
int fp(int a, int p) {
int base = 1;
while(p) {
if(p & 1) base = mul(base, a);
a = mul(a, a); p >>= 1;
}
return base;
}
int inv(int x) {
return fp(x, mod - 2);
}
int check(int lim) {
int tot = 0;
tot = lim * (R - L - (pr - pl));
if(tot > M) return tot;
for(int i = pl; i <= pr && tot <= M; i++)
tot += max(lim - cnt[i], 0ll);
return tot;
}
void solve() {
N = read(); M = read(); L = read(); R = read();
num = 0;
for(int i = 1; i <= N; i++) a[i] = read(), date[++num] = a[i], cnt[i] = 0;
sort(a + 1, a + N + 1);
sort(date + 1, date + num + 1);
num = unique(date + 1, date + num + 1) - date - 1;
for(int i = 1; i <= N; i++) a[i] = lower_bound(date + 1, date + num + 1, a[i]) - date, cnt[a[i]]++;
pl = lower_bound(date + 1, date + num + 1, L) - date;
pr = upper_bound(date + 1, date + num + 1, R) - date - 1;
l = 0, r = N + M;
while(l < r) {
int mid = l + r >> 1;
if(check(mid) <= M) l = mid + 1;
else r = mid;
}
int ans = fp(fac[l - 1], R - L - (pr - pl));
for(int i = 1; i <= num; i++)
if(i >= pl && i <= pr) ans = mul(ans, fac[max(cnt[i], l - 1)]);
else ans = mul(ans, fac[cnt[i]]);
ans = mul(ans, fp(l, M - check(l - 1)));//把少了的补上
cout << mul(fac[N + M], inv(ans)) << '\n';
}
signed main() {
fac[0] = 1;
for(int i = 1; i <= (int) 2e7; i++) fac[i] = mul(i, fac[i - 1]);
for(int T = read(); T--; solve());
return 0;
}
/*
2
3 3 5 7
1 3 4
3 3 1 2
1 3 4
*/

洛谷P4561 [JXOI2018]排序问题(二分 期望)的更多相关文章

  1. 洛谷 P2680 运输计划-二分+树上差分(边权覆盖)

    P2680 运输计划 题目背景 公元 20442044 年,人类进入了宇宙纪元. 题目描述 公元20442044 年,人类进入了宇宙纪元. L 国有 nn 个星球,还有 n-1n−1 条双向航道,每条 ...

  2. 洛谷P4983 忘情 (WQS二分+斜率优化)

    题目链接 忘情水二分模板题,最优解对划分段数的导数满足单调性(原函数凸性)即可使用此方法. 详细题解洛谷里面就有,不啰嗦了. 二分的临界点让人有点头大... #include<bits/stdc ...

  3. 并不对劲的bzoj5322:loj2543:p4561:[JXOI2018]排序问题

    题目大意 \(T\)(\(T\leq10^5\))组询问 每次给出\(n,m,l,r\),和\(n\)个数\(a_1,a_2,...,a_n\),要找出\(m\)个可重复的在区间\([l,r]\)的数 ...

  4. 洛谷 P1163"银行贷款"(二分)

    传送门 题解: 二分月利率,假设当前判断的月利率为x: 那么如何判断x是大了还是小了呢? 下面来分析一下Check()函数: bool Check(double x) { double tot=a; ...

  5. 洛谷P1850 换教室 [noip2016] 期望dp

    正解:期望dp 解题报告: 哇我发现我期望这块真的布星,可能在刷了点儿NOIp之后会去搞一波期望dp的题...感觉连基础都没有打扎实?基础概念都布星! 好那先把这题理顺了嗷qwq 首先我们看到期望就会 ...

  6. 【洛谷P1462】【二分+堆优化dij】

    题目描述 在艾泽拉斯,有n个城市.编号为1,2,3,...,n. 城市之间有m条双向的公路,连接着两个城市,从某个城市到另一个城市,会遭到联盟的攻击,进而损失一定的血量. 每次经过一个城市,都会被收取 ...

  7. 2018.09.26洛谷P3957 跳房子(二分+单调队列优化dp)

    传送门 表示去年考普及组的时候失了智,现在看来并不是很难啊. 直接二分答案然后单调队列优化dp检验就行了. 注意入队和出队的条件. 代码: #include<bits/stdc++.h> ...

  8. 【洛谷p3994】Highway 二分+斜率优化DP

    题目大意:给你一颗$n$个点的有根树,相邻两个点之间有距离,我们可以从$x$乘车到$x$的祖先,费用为$dis\times P[x]+Q[x]$,问你除根以外每个点到根的最小花费. 数据范围:$n≤1 ...

  9. 洛谷P3939 数颜色 二分查找

    正解:二分 解题报告: 传送门! 话说其实我开始看到这题想到的是分块,,, 但是显然不用这么复杂,,,因为仔细看下这题,会发现每次只改变相邻的兔子的位置 所以开个vector(或者开个数组也成QwQ( ...

随机推荐

  1. 解决Java中There is no getter for property XXX'XXX' in 'class XXX'的问题

    当你出现There is no getter for property XXX'XXX' in 'class XXX'时, 就是在你的这个类中没有找到你这个属性. 检查两个地方 1.你的返回值类型是否 ...

  2. C语言中assert()断言函数的概念及用法

    断言函数的格式如下所示: void assert (int expression);如果参数expression等于零,一个错误消息将会写入到设备的标准错误集并且会调用abort函数,就会结束程序的执 ...

  3. com.javax.servlet 慢慢看完慢慢学完

    1.接口 RequestDispatcher 类说明 定义一个对象,从客户端接收请求,然后将它发给服务器的可用资源 (例如Servlet.CGI.HTML文件.JSP文件).Servlet引擎创 建r ...

  4. mongo-spark-读取不同的库数据和写入不同的库中

    mongo-spark-读取不同的库数据和写入不同的库中 package com.example.app import com.mongodb.spark.config.{ReadConfig, Wr ...

  5. 2016 ACM/ICPC亚洲区青岛站现场赛(部分题解)

    摘要 本文主要列举并求解了2016 ACM/ICPC亚洲区青岛站现场赛的部分真题,着重介绍了各个题目的解题思路,结合详细的AC代码,意在熟悉青岛赛区的出题策略,以备战2018青岛站现场赛. HDU 5 ...

  6. python函数的参数细节

    按"指针"传递 python中变量赋值.参数传递都是通过"指针"拷贝的方式进行的.除了按"指针"拷贝,还有一种按值拷贝的方式,关于按值.按指 ...

  7. SpringBoot之Swagger2的使用

    Swagger是一组围绕OpenAPI规范构建的开源工具,可帮助设计.构建.记录和使用REST API.简单说下,它的出现就是为了方便进行测试后台的restful形式的接口,实现动态的更新,当我们在后 ...

  8. 分享一个用QT实现的Mjpeg-streamer客户端(简易版)

    mainWindow代码如下(由于篇幅问题,子窗口代码不贴出了,有需要源码的可以留下邮箱): /* * Author : 博客园 Lance# */ #include "mainwindow ...

  9. word2vec初探

    在自然语言处理入门里我们提到了词向量的概念,tf-idf的概念,并且在实际的影评正负面预测项目中使用了tf-idf,取得了还算不错的效果.这一篇,我们来尝试一下使用来自google的大名鼎鼎的word ...

  10. 腾讯云图片鉴黄集成到C#

    官方文档:https://cloud.tencent.com/document/product/641/12422 请求官方API及签名的生成代码如下: var urlList = new List& ...