令$S$表示对于某一种抽卡顺序中某一段长度为$k$的段全部被抽到的时间(这里没有期望)所构成的集合,根据$min-max$容斥的公式,有$E(\min(S))=\sum_{T\subseteq S}(-1)^{|T|+1}E(\max(T))$(其中$E(\min(S))$即为答案)
求$E(\max(T))$,设$k$表示$T$中所对应的段所覆盖的卡片数量,那么$E(\max(T))$显然只与$k$的大小有关,问题即在$m$张卡片中选出指定的$k$张卡片期望步数
每次抽中$k$张卡片中新卡片,都需要期望$\frac{m}{k-i}$(i为以抽走的卡片)步,因此得到$E(\max(T))=\sum_{i=1}^{k}\frac{m}{i}$
当$T$中同时有以$i$和$j$为开头的段且$i+1<j\le i+k$,那么这些$T$的总贡献一定为0($i+1$选与不选相互抵消),因此有贡献的段一定是长度为$k$或$k+1$的段且不能相邻或相交
为了更好的构造,放宽一些限制,允许$k+1$的段与后面的段相邻,显然这一部分的贡献为0,不影响答案
构造:将长度为$n$的一段中选出若干段不相交的长度为$k+1$的段,然后将其中任意段的结尾删除,容易证明这样必然能构造出所有解且不会重复
设生成函数为$g_n(x)$,即$x^{i}$的系数为覆盖了$i$个位置的$(-1)^{|T|}$之和,则有$g_{n}(x)=\sum_{i=0}^{\lfloor\frac{n}{k+1}\rfloor}c(n-ik,i)\cdot (x^{k+1}-x^{k})^{i}$
解释一下这个式子:$i$枚举段数,组合数即在选中的位置前再补上$k$个数,$(x^{k+1}-x^{k})^{i}$中$x^{k+1}$有两段即贡献为1,而$x^{k}$为一段即贡献为-1
但$[n-k+1,n]$无法通过这种构造选择,不妨强制选择最后$k$个,所对应的生成函数为$-x^{k}g_{n-k}(x)$($g_{n}(x)$仅表示这种构造下的和,因此恰好不能再选择$[n-2k+1,n-k]$)
设原序列中每一个连续段长度为$l_{i}$,那么问题相当于要求$-\sum_{i=k}^{m}\prod_{j=1}^{t}(g_{l_{j}}(x)-x^{k}g_{l_{j}-k}(x))[i])\cdot \sum_{j=1}^{i}\frac{m}{i}$
问题即如何求出$g_{n}(x)$,直接$o(\frac{m^{2}}{k^{2}})$暴力求就可以了,这些多项式相乘可以用分治ntt或不断选择最小的两个合并(哈夫曼树)来卡常就可以过了

  1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 200005
4 #define mod 998244353
5 struct poly{
6 int n;
7 vector<int>a;
8 }o,t[N];
9 priority_queue<pair<int,int> >q;
10 int n,m,k,ans,a[N],fac[N],inv[N],f[N],rev[N<<1];
11 int c(int n,int m){
12 return 1LL*fac[n]*inv[m]%mod*inv[n-m]%mod;
13 }
14 int ksm(int n,int m){
15 if (!m)return 1;
16 int s=ksm(n,m>>1);
17 s=1LL*s*s%mod;
18 if (m&1)s=1LL*s*n%mod;
19 return s;
20 }
21 poly add(poly x,poly y){
22 if (x.n<y.n)swap(x,y);
23 for(int i=0;i<=y.n;i++)x.a[i]=(x.a[i]+y.a[i])%mod;
24 return x;
25 }
26 poly left(poly x,int k){
27 poly y;
28 y.n=x.n+k;
29 for(int i=0;i<k;i++)y.a.push_back(0);
30 for(int i=0;i<=x.n;i++)y.a.push_back(x.a[i]);
31 return y;
32 }
33 poly mul(poly x,int k){
34 poly y;
35 y.n=x.n;
36 for(int i=0;i<=y.n;i++)y.a.push_back(1LL*x.a[i]*k%mod);
37 return y;
38 }
39 poly ntt(poly x,int m,int p){
40 for(int i=0;i<m;i++)
41 if (i<rev[i])swap(x.a[i],x.a[rev[i]]);
42 for(int i=2;i<=m;i*=2){
43 int t=(i>>1),s=ksm(3,(mod-1)/i);
44 if (p)s=ksm(s,mod-2);
45 for(int j=0;j<m;j+=i)
46 for(int k=0,w=1;k<t;k++,w=1LL*w*s%mod){
47 int y=1LL*w*x.a[j+k+t]%mod;
48 x.a[j+k+t]=(x.a[j+k]+mod-y)%mod;
49 x.a[j+k]=(x.a[j+k]+y)%mod;
50 }
51 }
52 if (p)
53 for(int i=0;i<m;i++)x.a[i]=1LL*x.a[i]*ksm(m,mod-2)%mod;
54 return x;
55 }
56 poly mul(poly x,poly y){
57 int m=1;
58 while (m<=x.n+y.n)m*=2;
59 for(int i=0;i<m;i++)rev[i]=((rev[i>>1]>>1)|((i&1)*m/2));
60 for(int i=x.n+1;i<m;i++)x.a.push_back(0);
61 x=ntt(x,m,0);
62 for(int i=y.n+1;i<m;i++)y.a.push_back(0);
63 y=ntt(y,m,0);
64 for(int i=0;i<m;i++)x.a[i]=1LL*x.a[i]*y.a[i]%mod;
65 x.n+=y.n;
66 return ntt(x,m,1);
67 }
68 poly mi(int k){
69 poly ans;
70 ans.n=k;
71 for(int i=0;i<=k;i++)ans.a.push_back(c(k,i));
72 for(int i=k-1;i>=0;i-=2)ans.a[i]=mod-ans.a[i];
73 return ans;
74 }
75 poly calc(int n){
76 poly ans;
77 ans.n=0;
78 ans.a.push_back(0);
79 for(int i=0;i<=n/(k+1);i++)ans=add(ans,left(mul(mi(i),c(n-i*k,i)),i*k));
80 return ans;
81 }
82 int main(){
83 scanf("%d%d",&n,&k);
84 fac[0]=inv[0]=inv[1]=1;
85 for(int i=1;i<=n;i++)fac[i]=1LL*fac[i-1]*i%mod;
86 for(int i=2;i<=n;i++)inv[i]=1LL*(mod-mod/i)*inv[mod%i]%mod;
87 for(int i=1;i<=n;i++)f[i]=(f[i-1]+1LL*n*inv[i])%mod;
88 for(int i=1;i<=n;i++)inv[i]=1LL*inv[i-1]*inv[i]%mod;
89 for(int i=1;i<=n;i++)scanf("%d",&a[i]);
90 sort(a+1,a+n+1);
91 for(int i=1,j=1;i<=n;i=j){
92 for(;(j<=n)&&(a[j]+1==a[j+1]);j++);
93 j++;
94 if (j-i>=k){
95 t[++m]=add(calc(j-i),mul(left(calc(j-i-k),k),mod-1));
96 q.push(make_pair(-t[m].n,m));
97 }
98 }
99 for(int i=1;i<m;i++){
100 int x=q.top().second;
101 q.pop();
102 int y=q.top().second;
103 q.pop();
104 t[x]=mul(t[x],t[y]);
105 q.push(make_pair(-t[x].n,x));
106 }
107 int x=q.top().second;
108 for(int i=k;i<=t[x].n;i++)ans=(ans+1LL*t[x].a[i]*f[i])%mod;
109 printf("%d",mod-ans);
110 }

[loj3315]抽卡的更多相关文章

  1. 三色抽卡游戏 博弈论nim

    你的对手太坏了!在每年的年度三色抽卡游戏锦标赛上,你的对手总是能打败你,他的秘诀是什么? 在每局三色抽卡游戏中,有n个卡组,每个卡组里所有卡片的颜色都相同,且颜色只会是红(R).绿(G).蓝(B)中的 ...

  2. 51nod 抽卡大赛

    抽卡大赛 链接 分析: $O(n^4)$的做法比较好想,枚举第i个人选第j个,然后背包一下,求出有k个比他大的概率. 优化: 第i个人,选择一张卡片,第j个人选的卡片大于第i个人的概率是$p_j$,那 ...

  3. [CSP-S模拟测试]:抽卡(概率DP)

    题目描述 水上由岐最近在肝手游,游戏里有一个氪金抽卡的活动.有$n$种卡,每种卡有 3 种颜色.每次抽卡可能什么也抽不到,也可能抽到一张卡.每氪金一次可以连抽 m 次卡,其中前$m−1$次抽到第$i$ ...

  4. Java实现 蓝桥杯 算法提高 抽卡游戏

    试题 算法提高 抽卡游戏 某个抽卡游戏卡池抽出限定卡的概率为p,该游戏有一个"井"的机制,抽满k次卡后直接送这张限定卡.试求获得这张限定卡需要的期望抽卡次数.输入为一行,用空格隔开 ...

  5. 十二省NOI“省选”联考模测(第二场)A抽卡大赛

    /* dp维护整体的概率, 每次相当于回退一格然后重新dp一格 */ #include<cstdio> #include<algorithm> #include<iost ...

  6. 51nod 1850 抽卡大赛 (十二省联考模测) DP

    O(n4)O(n^4)O(n4)的DP很好想,但是过不了.来看看O(n3)O(n^3)O(n3)的把. Freopen的博客 CODE #include <cstdio> #include ...

  7. [51Nod1850] 抽卡大赛

    link $solution:$ 朴素 $dp$,暴力枚举选择 $i$ 号人的第 $j$ 张卡片,朴素 $dp$ 即可,时间复杂度 $O(n^4)$ . 考虑对于朴素 $dp$ 的优化,发现其实是一个 ...

  8. C#入门经典第十章例题 - - 卡牌

    1.库 using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ...

  9. 卡片抽奖插件 CardShow

    这个小项目(卡片秀)是一个卡片抽奖特效插件,用开源项目这样的词语让我多少有些羞愧,毕竟作为一个涉世未深的小伙子,用项目的标准衡量还有很大差距.不过该案例采用 jQuery 插件方式编写,提供配置参数并 ...

随机推荐

  1. 手机淘宝轻店业务 Serverless 研发模式升级实践

    一.前言 随着 Serverless 在业界各云平台落地,阿里内部 Serverless 研发平台.各种研发模式也在业务中逐步落地,如火如荼.在此契机下,淘系团队启动了轻店 Serverless 研发 ...

  2. 基于注解实现jackson动态JsonProperty

    基于注解实现jackson动态JsonProperty @JsonProperty 此注解用于属性上,作用是把该属性的名称序列化为另外一个名称,如把trueName属性序列化为name,但是值是固定的 ...

  3. 2021MySQL 8.0.26安装教程,目前最新版(详细全面)

    MySQL 8 要比 MySQL 5.7 快 2 倍,还带来了大量的改进和更快的性能!所以为什么不用MySQL8呢!下面是MySQL 8.0.26的安装教程. 安装网址: https://dev.my ...

  4. Linux系统安装MySql5.7并通过sql脚本导入数据

    为了下载到的MySQL版本和目标系统相互兼容,在开启之前,最好了解目标系统的相关信息. 查询系统版本: cat /etc/issue 查看系统位数 getconf LONG_BIT 选择MySQL 根 ...

  5. C语言中while 语句

    while的执行顺序 while 循环的执行顺序非常简单,它的格式是: while (表达式) { 语句: } 概念:当表达式为真,则执行下面的语句:语句执行完之后再判断表达式是否为真,如果为真,再次 ...

  6. 小白自制Linux开发板 八. Linux音频驱动配置

    不知不觉小白自制开发板系列已经到第八篇了,本篇要配置的是音频驱动,也算是硬件部分的最后一片了,积攒的文章也差不多全放完了,后续更新可能会放缓,还请见谅. 对于F1C200s是自带了多媒体处理功能的,所 ...

  7. logstash收集的日志输出到elasticsearch中

    logstash收集的日志输出到elasticsearch中 一.需求 二.实现步骤 1.编写pipeline文件 1.`elasticsearch`配置参数解析: 2.可能会报的一个异常 2.准备测 ...

  8. [调试笔记] 晚测5 T1 容易题

    众所周知,sbwzx在考试一结束就嚷嚷T1是个sb题.那他为什么调了2小时才调出来呢?快和小编一起看看吧. Sb题:指除了sbwzx别人都能做出来的题 1.CE:震惊!sbwzx竟然连map都不会用, ...

  9. Qt字符编码小知识

    1.VS2010默认编码是GBK,Qt5的内置编码是utf-8,想要在VS2010及其以上版本,优雅的使用utf-8的字符编码需要 // Coding: UTF-8(BOM) #if defined( ...

  10. Python课程笔记(六)

    今天上课补上了上次未学完比较重点的鼠标和键盘事件,同时开始学习运用turtle进行绘图. 本次课程的代码: https://gitee.com/wang_ming_er/python_course_l ...