2018.09.19 atcoder Card Game for Three(组合数学)
传送门
简单组合数学想优化想了半天啊233。
我们只需考虑翻开n张A,b张B,c张C且最后一张为A的选法数。
显然还剩下m+k−b−cm+k-b-cm+k−b−c张牌没有选。
这样的话无论前n+b+cn+b+cn+b+c张牌怎么选,方案数会乘上一个3m+k−b−c3^{m+k-b-c}3m+k−b−c。
继续讨论。
我们应该从前n+b+c−1n+b+c-1n+b+c−1中选出n−1n-1n−1个A(因为最后一个一定是A)。
剩下的要么是B要么是C。
我们不妨令b+c=i。
那么有:
ans=∑(i=0m+k3m+k−i(n+i−1n−1)∑[b+c=i],b≤m,c≤k)(ib)ans=\sum( _{i=0} ^{m+k} 3^{m+k-i}\binom {n+i-1} {n-1}\sum _{[b+c=i],b\le m,c\le k}) \binom {i} {b}ans=∑(i=0m+k3m+k−i(n−1n+i−1)∑[b+c=i],b≤m,c≤k)(bi)
然后发现前面的一坨都不能优化。
只能在最后一部分做文章。
所以如何优化?
发现我们从i变到i+1的过程相当于杨辉三角向下移动一行的情况。
因此讨论一下边界分情况转移就行了。
代码:
#include<bits/stdc++.h>
#define N 300005
#define mod 1000000007
#define ll long long
using namespace std;
ll up,n,m,k;
ll ans=0,fac[N*3],ifac[N*3],mul[N*3];
inline ll calc(int a,int b){return fac[a]*ifac[b]%mod*ifac[a-b]%mod;}
inline ll ksm(ll x,int p){
ll ret=1;
while(p){
if(p&1)ret=ret*x%mod;
x=x*x%mod,p>>=1;
}
return ret;
}
int main(){
cin>>n>>m>>k,up=n+m+k,fac[0]=mul[0]=ifac[1]=ifac[0]=1;
for(ll i=2;i<=up;++i)ifac[i]=(mod-mod/i)*ifac[mod%i]%mod;
for(ll i=1;i<=up;++i)mul[i]=mul[i-1]*3%mod,(ifac[i]*=ifac[i-1])%=mod,fac[i]=fac[i-1]*i%mod;
if(m<k)m^=k,k^=m,m^=k;
for(ll i=0,j=1;i<=m+k;++i){
(ans+=calc(n-1+i,n-1)*mul[m+k-i]%mod*j%mod)%=mod;
if(i<k)(j<<=1)%=mod;
else if(i>=m)(j+=j-calc(i,k)-calc(i,i-m))%=mod;
else (j+=j-calc(i,k))%=mod;
}
cout<<(ans+mod)%mod;
return 0;
}
2018.09.19 atcoder Card Game for Three(组合数学)的更多相关文章
- 2018.09.19 atcoder AtCoDeer and Rock-Paper(贪心)
传送门 sb贪心啊. 显然能选帕子就选帕子. 首先假设第一个人全出石头. 考虑把一些石头修改成帕子. 这样贡献只增不减,加起来就是答案. 代码: #include<bits/stdc++.h&g ...
- 2018.09.19 atcoder AtCoDeer and Election Report(贪心)
传送门 很有意思的一道贪心. 就是每次翻最小的倍数来满足条件. 代码: #include<bits/stdc++.h> #define ll long long using namespa ...
- 2018.09.19 atcoder Snuke's Subway Trip(最短路)
传送门 就是一个另类最短路啊. 利用颜色判断当前节点的最小花费的前驱边中有没有跟当前的边颜色相同的. 如果有这条边费用为0,否则费用为1. 这样跑出来就能ac了. 代码: #include<bi ...
- 2018.09.19 atcoder Snuke's Coloring(思维题)
传送门 谁能想到这道题会写这么久. 本来是一道很sb的题啊. 就是每次选一个点只会影响到周围的九个方格,随便1e9进制就可以hash了,但是我非要作死用stl写. 结果由于技术不够高超,一直调不出来. ...
- 2018.12.19 atcoder Iroha and a Grid(组合数学)
传送门 组合数学好题. 给你一个hhh行www列的网格,其中左下角aaa行bbb列不能走,问从左上角走到右下角有多少种走法(每次只能向右或者向下) 我们考虑分步计数. 我们一共能走的区域是总网格区域去 ...
- 2018.09.23 atcoder Boxes and Candies(贪心)
传送门 一道挺有意思的贪心. 从1到n依次满足条件. 注意要特判第一个数已经大于x的情况. 但是如何贪心吃呢? 如果靠左的数没有越界,我们吃靠右的数. 原因是下一次靠右的数就会成为靠左的数,相当于多贡 ...
- 2018.09.22 atcoder Snuke's Coloring 2(线段树+单调栈)
传送门 就是给出一个矩形,上面有一些点,让你找出一个周长最大的矩形,满足没有一个点在矩形中. 这个题很有意思. 考虑到答案一定会穿过中线. 于是我们可以把点分到中线两边. 先想想暴力如何解决. 显然就 ...
- 2018.09.22 atcoder Integers on a Tree(构造)
传送门 先考虑什么时候不合法. 第一是考虑任意两个特殊点的权值的奇偶性是否满足条件. 第二是考虑每个点的取值范围是否合法. 如果上述条件都满足的话就可以随便构造出一组解. 代码: #include&l ...
- 2018.09.21 atcoder An Invisible Hand(贪心)
传送门 简单贪心啊. 这题显然跟t并没有关系,取差量最大的几组买入卖出就行了. 于是我们统计一下有几组差量是最大的就行了. 代码: #include<bits/stdc++.h> #def ...
随机推荐
- C++Primer笔记-----day08
==========================================================================day08===================== ...
- check_http检查http服务
选 项 说 明 -H, --hostname=ADDRESS 主机名或域名 -I, --IP-address=ADDRESS server的IP地址,用于在不能DNS的情况下 -p, --port=I ...
- NISP视频知识点总结
身份认证访问控制安全审计本章实验 ===密码学=====古典密码 算法本身的保密性近代密码 机械密码\机电 密码打字密码机轮转机现代密码 基于密钥公钥密码 公钥==================对称 ...
- 如何打开Windows Server 2008 R2的域安全策略
今天安装了Windows Server 2008 R2系统,并且建了域环境,在添加新用户的时候,发现用简单的密码时域安全策略提示密码复杂度不够,于是我就想在域安全策略里面把密码复杂度降低一点,但是很快 ...
- spark UDF函数
Spark(Hive) SQL中UDF的使用(Python):http://www.tuicool.com/articles/3yMBNb7
- python mysql connector
install pip install mysql-connector-python-rf 报错 从https://dev.mysql.com/downloads/connector/python ...
- 给vim编辑器自动添加行号
1.只改变当前用户的vim 在~目录下 vim .vimrc添加一行 set number 即可(普通用户权限即可) 2. 改变所有用户的vim 打开文件 /etc/vimrc 添加一行 set n ...
- windows本地blast
详细可参考https://www.jianshu.com/p/2f125cdf8262:https://blog.csdn.net/qq_34296043/article/details/544277 ...
- git冲突解决方案 Intellij IDEA
一般在团队合作开发一个项目的过程中,经常出现两个人同时修改一个文件然后都向主master提交commit,这样就会产生冲突(conflict),那么这种情况如何解决? 1 新建分支 如果项目的主分支是 ...
- Oracle 数据库的绑定变量特性及应用
Oracle 数据库的绑定变量特性及应用[-----]转载自https://www.cnblogs.com/rootq/(原地址) 关键词: 绑定变量(binding variable),共享池(sh ...