令$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. Windows系统安装Java步骤

    今天学习到Burp Suite的使用,提示到安装Burp Suite需要安装Java环境. 于是乎,本弱鸡开启了漫长的Java环境安装之路~ 一.Java SE版本众多,在这里推荐下载Java1.8版 ...

  2. Java项目中常用的的五大设计原则

    今天我们一起来聊聊关于设计原则相关的知识点. SOLID五大原则是什么 SRP 单一责任原则 单一责任原则,从名字上我们就能比较好的去理解它.这项原则主张一个对象只专注于单个方面的逻辑,强调了职责的专 ...

  3. WPF中的命令(Command)

    这节来讲一下WPF中的命令(Command)的使用. [认识Command] 我们之前说过,WPF本身就为我们提供了一个基础的MVVM框架,本节要讲的命令就是其中一环,通过在ViewModel中声明命 ...

  4. UltraSoft - Alpha - 测试报告

    遇到的bug bug:在vue.config.js里配置proxy,并修改请求的url后仍无法连接到后端. 解决: url最后忘了'/',导致和后端不匹配,会有404.500等错误. 后端服务未打开或 ...

  5. 【二食堂】Alpha - Scrum Meeting 5

    Scrum Meeting 5 例会时间:4.15 12:30 - 13:00 进度情况 组员 昨日进度 今日任务 李健 1. 主页搭建结束issue2. 与后端协商确定接口的设计3. 查找文本区域功 ...

  6. BUAA_2020_软件工程_结对项目作业

    项目 内容 这个作业属于哪个课程 班级博客 这个作业的要求在哪里 作业要求 我在这个课程的目标是 掌握软件工程的思路方法 这个作业在哪个具体方面帮助我实现目标 学习结对编程 教学班级 006 项目地址 ...

  7. Asp.net Core C#进行筛选、过滤、使用PredicateBuilder进行动态拼接lamdba表达式树并用作条件精准查询,模糊查询

    在asp.net core.asp.net 中做where条件过滤筛选的时候写的长而繁琐不利于维护,用PredicateBuilder进行筛选.过滤.LInq配合Ef.core进行动态拼接lamdba ...

  8. 21.6.21 test

    \(NOI\) 模拟赛 字符串滚出 \(OI\) 看到题目名称,\(T1\) 串,\(T2\) 两个串,\(T3\) K个串,我 \(\cdots\),血压已经上来了. \(T1\) 写了 \(O(n ...

  9. 【Azure 应用服务】App Service For Linux 部署Java Spring Boot应用后,查看日志文件时的疑惑

    编写Java Spring Boot应用,通过配置logging.path路径把日志输出在指定的文件夹中. 第一步:通过VS Code创建一个空的Spring Boot项目 第二步:在applicat ...

  10. P4430 小猴打架

    P4430 小猴打架 题目意思就是让你求,在网格图中(任意两点都有边)的生成树的个数(边的顺序不同也算不同的方案). 首先我们考虑一个生成树,由于一定有n-1条边,单单考虑添加边的顺序,根据乘法原理, ...