Portal --> broken qwq

Description

  有个口袋,一开始里面有\(N\)个球,接下来进行\(M\)次操作,每次可以选择往里面放一个球或者从里面拿一个球出来,在这\(M\)次操作之后,要取\(K\)个球出来,对于每一种操作方式,都有取出\(K\)个球的方案数(球两两不同),求方案总数

​  数据范围:\(T<=500,N<=10^9,M<=10^9,K<=300\),保证\(N>=M+K\)

  

Solution

​  首先考虑最朴素的做法,我们可以考虑在\(M\)次操作中有\(i\)次是放球的,\(M-i\)次是取球的,那么可以得到这样的一个式子:

\[ans=\sum\limits_{i=0}^m\binom m i\binom {n-m+2*i} K
\]

​  然后看一下数据范围:哦豁凉凉

​  显然我们需要探求一个时间复杂度只与\(K\)相关的算法,所以我们换一个角度思考问题

  考虑转化一下这个操作:假设我们一开始先拿走\(M\)个球(因为数据有保证所以不用担心不够拿的问题),那么接下来的每次操作就变成了:要么不动,要么往袋子里面加入\(2\)个球

​  这样一来在操作结束之后,我们最终的球可以按照来源分为两类:一类是原本的\(N-M\)个球(称为第一类),一类是后面操作中加入的球(称为第二类),现在我们要在这些球中取\(K\)个

​  假设这\(K\)个球中,有\(x\)个是第一类中取的,有\(K-x\)个是第二类中取的,第一类的贡献显然是“从\(N-M\)个中选\(x\)个”也就是\(\binom {N-M} x\),接下来考虑第二类的贡献怎么算

​  考虑dp,每一次操作是加入一对球,那么我们设\(f[i][j]\)表示:我们拿走了\(i\)个球,并且这\(i\)个球属于的加入操作的集合大小为\(j\)(也就是说选了\(j\)个加入操作中加入的球,如果说有一次操作加入的两个球都被拿走了,那么集合大小还是\(1\))的取球方案数,不难列出递推式:

\[f[i][j]=2*f[i-1][j-1]+f[i-2][j-1]
\]

  具体一点就是,前半部分是在这次操作中取\(1\)个球,可以选择这次操作加入的第一个球或者第二个球(球两两之间不同嘛);后半部分是将这次操作中的\(2\)个球都取上

  那么在第二类中取\(x\)个球的贡献就是

\[\sum\limits_{j=\lceil\frac{x}{2}\rceil}^x\binom M j f[x][j]\cdot 2^{M-j}
\]

​  具体一点就是:枚举涉及的加入操作集合大小\(j\),然后要在\(M\)个操作中钦定\(j\)个操作为加入操作,然后\(f[x][j]\)就是贡献,剩下还有\(M-j\)个操作,那么这些操作不管是加球还是什么都不做都可以,所以是\(2^{M-j}\)

​  所以总的式子就是:

\[ans=\sum\limits_{i=0}^K\sum\limits_{j=\lceil\frac{K-i}{2}\rceil}^{K-i}\binom {N-M}{i}\binom M j f[K-i][j]\cdot 2^{M-j}
\]

  中间的两个组合数的话。。不难发现从\(\binom n m\)推到\(\binom n {m+1}\)只要乘上一个\(\frac{n-m}{m+1}\)即可,所以我们可以一路递推上去就好了

​  于是乎就可以\(O(K^2)\)搞定这题啦ovo

  

  然而ckw大爷有不同的做法qwq实际上这题可以简单粗暴直接推式子但是qwq我这种蒟蒻推不动啊qwq

  不过。。mark:我们可以将组合数\(\binom x i\)看成一个关于\(x\)的\(i\)次多项式(因为写成阶乘相除形式之后拆个括号就很明显了)

​  

  代码大概长这个样子

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N=310,MOD=1e9+7;
int f[N][N],inv[N];
int n,m,K,T,ans;
int plu(int x,int y){return (1LL*x+y)%MOD;}
int mul(int x,int y){return 1LL*x*y%MOD;}
int ksm(int x,int y){
int ret=1,base=x;
for (;y;y>>=1,base=mul(base,base))
if (y&1) ret=mul(ret,base);
return ret;
}
void prework(int n){
f[0][0]=1;
for (int i=1;i<=n;++i){
for (int j=i/2;j<=i;++j)
f[i][j]=plu(mul(2,f[i-1][j-1]),f[i-2][j-1]);
}
for (int i=0;i<N;++i)
inv[i]=ksm(i,MOD-2);
}
void dp(){
int tmp1=1,tmp2,ttmp,pw;
for (int i=0;i<=K;++i){
tmp2=1; ttmp=(K-i+1)/2; pw=1;
for (int j=0;j<ttmp;++j) tmp2=mul(tmp2,mul(m-j,inv[j+1]));
pw=ksm(2,m-(K-i+1)/2);
for (int j=ttmp;j<=K-i;++j){
ans=plu(ans,mul(tmp1,mul(tmp2,mul(pw,f[K-i][j]))));
tmp2=mul(tmp2,mul(m-j,inv[j+1]));
pw=mul(pw,inv[2]);
}
tmp1=mul(tmp1,mul(n-m-i,inv[i+1]));
}
} int main(){
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
#endif
scanf("%d",&T);
prework(300);
for (int o=1;o<=T;++o){
scanf("%d%d%d",&n,&m,&K);
ans=0;
dp();
printf("%d\n",ans);
}
}

【2016北京集训】crash的游戏的更多相关文章

  1. (2016北京集训十)【xsy1528】azelso - 概率期望dp

    北京集训的题都是好题啊~~(于是我爆0了) 注意到一个重要的性质就是期望是线性的,也就是说每一段的期望步数可以直接加起来,那么dp求出每一段的期望就行了... 设$f_i$表示从$i$出发不回到$i$ ...

  2. 2016北京集训测试赛(十七)Problem A: crash的游戏

    Solution 相当于要你计算这样一个式子: \[ \sum_{x = 0}^m \left( \begin{array}{} m \\ x \end{array} \right) \left( \ ...

  3. [2016北京集训测试赛17]crash的游戏-[组合数+斯特林数+拉格朗日插值]

    Description Solution 核心思想是把组合数当成一个奇怪的多项式,然后拉格朗日插值..:哦对了,还要用到第二类斯特林数(就是把若干个球放到若干个盒子)的一个公式: $x^{n}=\su ...

  4. [2016北京集训试题6]魔法游戏-[博弈论-sg函数]

    Description Solution 首先,每个节点上的权值可以等价于该节点上有(它的权的二进制位数+1)个石子,每次可以拿若干个石子但不能不拿. 然后就发现这和NIM游戏很像,就计算sg函数em ...

  5. 【2016北京集训测试赛(八)】 crash的数列 (思考题)

    Description 题解 题目说这是一个具有神奇特性的数列!这句话是非常有用的因为我们发现,如果套着这个数列的定义再从原数列引出一个新数列,它居然还是一样的...... 于是我们就想到了能不能用多 ...

  6. (2016北京集训十三)【xsy1531】魔法游戏 - Nim游戏

    题解: 好题!我的结论很接近正解了... 把一个数化成二进制,每次至少要拿走一位,最多全拿走,不能不拿.那么这就是一个经典的Nim问题了,子树异或起来就是根节点的答案,随便递推一下就行了. 代码: # ...

  7. 【2016北京集训测试赛(十)】 Azelso (期望DP)

    Time Limit: 1000 ms   Memory Limit: 256 MB Description 题解 状态表示: 这题的状态表示有点难想...... 设$f_i$表示第$i$个事件经过之 ...

  8. 【2016北京集训测试赛(二)】 thr (树形DP)

    Description 题解 (这可是一道很早就碰到的练习题然后我不会做不想做,没想到在Contest碰到欲哭无泪......) 题目大意是寻找三点对的个数,使得其中的三个点两两距离都为d. 问题在于 ...

  9. 【2016北京集训测试赛(十六)】 River (最大流)

    Description  Special Judge Hint 注意是全程不能经过两个相同的景点,并且一天的开始和结束不能用同样的交通方式. 题解 题目大意:给定两组点,每组有$n$个点,有若干条跨组 ...

随机推荐

  1. centos下JDK安装及环境变量配置

    由于centos安装自带openjdk,需要将其卸载后安装自己的jdk 卸载centos自带jdk 1.查找java :rpm -qa | grep java 2.卸载时提示权限不够,进入root目录 ...

  2. DeepLearning - Overview of Sequence model

    I have had a hard time trying to understand recurrent model. Compared to Ng's deep learning course, ...

  3. 联邦快递 IE和IP的区别 Fedex IE VS Fedex IP

    什么是FedEx IP? FedEx IP指的是联邦快递优先服务,时效比较快些,相对来说价格也比普通的高一些. 什么是FedEx IE? FedEx IE指的是联邦快递经济服务,时效与FedEx IP ...

  4. LCA最近公共祖先(Tarjan离线算法)

    这篇博客对Tarjan算法的原理和过程模拟的很详细. 转载大佬的博客https://www.cnblogs.com/JVxie/p/4854719.html 第二次更新,之前转载的博客虽然胜在详细,但 ...

  5. Java 学习笔记 ------第四章 认识对象

    本章学习目标: 区分基本类型与类类型 了解对象与参考的关系 从打包器认识对象 以对象观点看待数组 认识字符串的特性 一."=" 和 "==" 当=用于基本类型时 ...

  6. Dijkstra 最短路径算法 秒懂详解

    想必大家一定会Floyd了吧,Floyd只要暴力的三个for就可以出来,代码好背,也好理解,但缺点就是时间复杂度高是O(n³). 于是今天就给大家带来一种时间复杂度是O(n²),的算法:Dijkstr ...

  7. ImportError: No module named examples.tutorials.mnist

    Traceback (most recent call last):   File "nearest_neighbor.py", line 14, in <module> ...

  8. 201621123037 《Java程序设计》第3周学习总结

    #Week03-面向对象入门 1. 本周学习总结 初学面向对象,会学习到很多碎片化的概念与知识.尝试学会使用思维导图将这些碎片化的概念.知识点组织起来.请使用工具画出本周学习到的知识点及知识点之间的联 ...

  9. (转)用MongoDB 实现优酷API 缓存

    由于众所周知的原因, 邪恶的企业优酷于九月的某一天开始禁止第三方播放器加载视频API, 我不得不设置一个反向代理来绕过Flash 的跨域限制. 自此服务器压力激增, 导致用户体验大为劣化. 为了减少服 ...

  10. Windows搭建Log4Net+FileBeat+ELK日志分析系统过程

    参考博客:http://udn.yyuap.com/thread-54591-1-1.html ; https://www.cnblogs.com/yanbinliu/p/6208626.html ; ...