AT2070-[ARC061D]3人でカードゲーム/Card Game for Three【计数,组合数学】
正題
題目鏈接:https://www.luogu.com.cn/problem/AT2070
題目大意
有三堆卡牌各有n,m,kn,m,kn,m,k張,每張上寫了a/b/ca/b/ca/b/c,對于第1/2/31/2/31/2/3堆卡牌。然后開始從第一堆拿牌,然后根據(jù)拿到的牌在對應(yīng)的堆拿牌。
如果到一堆拿牌時沒有牌就結(jié)束,求第一張牌結(jié)束的方案數(shù)。
1≤n,m,k≤3×1051\leq n,m,k\leq 3\times 10^51≤n,m,k≤3×105
解題思路
顯然牌的序列我們不是很好處理因?yàn)椴皇琼樞蚰玫?#xff0c;我們可以操作每次取的堆的編號序列。
顯然它的長度不是固定的,我們枚舉其長度n+in+in+i(也就是除了nnn個111以外有iii個其他的)。
然后答案就是
∑i=0m+k3m+k?i(n+i?1i)∑i?k≤j≤m(ij)\sum_{i=0}^{m+k}3^{m+k-i}\binom{n+i-1}{i}\sum_{i-k\leq j\leq m}\binom{i}{j}i=0∑m+k?3m+k?i(in+i?1?)i?k≤j≤m∑?(ji?)
后面那個很難處理但是注意到區(qū)間的范圍是每次向前移動,而且上面那個值是每次加一,暴力拆開
∑i?k≤j≤m(ij)=∑i?k≤j≤m(i?1j?1)+(i?1j)\sum_{i-k\leq j\leq m}\binom{i}{j}=\sum_{i-k\leq j\leq m}\binom{i-1}{j-1}+\binom{i-1}{j}i?k≤j≤m∑?(ji?)=i?k≤j≤m∑?(j?1i?1?)+(ji?1?)
?2∑i?1?k≤j≤m(i?1j)?(i?1i?1?k)?(i?1m)\Rightarrow 2\sum_{i-1-k\leq j\leq m}\binom{i-1}{j}-\binom{i-1}{i-1-k}-\binom{i-1}{m}?2i?1?k≤j≤m∑?(ji?1?)?(i?1?ki?1?)?(mi?1?)
然后就可以O(n)O(n)O(n)遞推了。
時間復(fù)雜度:O(n+m+k)O(n+m+k)O(n+m+k)
code
#include<cstdio> #include<cstring> #include<algorithm> #define ll long long using namespace std; const ll N=1e6+10,P=1e9+7; ll n,m,k,ans,fac[N],inv[N],s[N],pw[N]; ll C(ll n,ll m) {return fac[n]*inv[m]%P*inv[n-m]%P;} signed main() {fac[0]=inv[0]=inv[1]=pw[0]=1;for(ll i=1;i<N;i++)pw[i]=pw[i-1]*3ll%P;for(ll i=2;i<N;i++)inv[i]=P-inv[P%i]*(P/i)%P;for(ll i=1;i<N;i++)fac[i]=fac[i-1]*i%P,inv[i]=inv[i-1]*inv[i]%P;scanf("%lld%lld%lld",&n,&m,&k);s[0]=1;ans=pw[m+k];for(ll i=1;i<=m+k;i++){s[i]=2*s[i-1]%P;if(i>m)(s[i]+=P-C(i-1,m))%=P;if(i>k)(s[i]+=P-C(i-1,i-k-1))%=P;(ans+=C(n+i-1,i)*s[i]%P*pw[m+k-i])%=P;}printf("%lld\n",ans);return 0; }總結(jié)
以上是生活随笔為你收集整理的AT2070-[ARC061D]3人でカードゲーム/Card Game for Three【计数,组合数学】的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 散热和风扇转速调节如何提高电脑风扇转速
- 下一篇: 51nod1227-平均最小公倍数【杜教