记录每一次操作的玩家为操作序列(去掉第一次),需要满足:$a$的个数为$n$且以$a$为结尾,$b$和$c$的个数分别不超过$m$和$k$

其所对应的概率:每一个字符恰好确定一张卡牌,因此即$3^{n+m+k-|s|}$

暴力枚举$b$和$c$的个数,即$\sum_{i=0}^{m}\sum_{j=0}^{k}{n+i+j-1\choose i}{n+j-1\choose j}3^{m+k-i-j}$

将组合数用阶乘展开,即$\sum_{i=0}^{m}\sum_{j=0}^{k}\frac{(n+i+j-1)!3^{m+k-i-j}}{(n-1)!i!j!}$

枚举$i+j=s$,即$\frac{\sum_{s=0}^{m+k}(n+s-1)!3^{m+k-s}\sum_{0\le i\le m,0\le s-i\le k}\frac{1}{i!(s-i)!}}{(n-1)!}$

关于后者显然是一个多项式乘法的形式,但由于模数是$10^{9}+7$,需要写一个拆系数fft/三模数ntt,复杂度为$o(n\log n)$且常数较大

 1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 300005
4 #define M (1<<20)
5 #define mod 1000000007
6 #define K 40000
7 #define cd complex<double>
8 #define PI acos(-1.0)
9 int n,m,k,ans,fac[M],inv[N],mi[M],rev[M];
10 cd a1[M],a2[M],b1[M],b2[M],c1[M],c2[M],c3[M],w[M];
11 void fft(cd *a,int p){
12 for(int i=0;i<M;i++)
13 if (i<rev[i])swap(a[i],a[rev[i]]);
14 for(int i=2;i<=M;i<<=1)
15 for(int j=0;j<M;j+=i)
16 for(int k=0;k<(i>>1);k++){
17 cd s=w[(i>>1)+k];
18 if (p)s=conj(s);
19 cd x=a[j+k],y=a[j+k+(i>>1)]*s;
20 a[j+k]=x+y;
21 a[j+k+(i>>1)]=x-y;
22 }
23 if (p){
24 for(int i=0;i<M;i++)a[i]/=M;
25 }
26 }
27 int main(){
28 fac[0]=inv[0]=inv[1]=mi[0]=1;
29 for(int i=1;i<M;i++)fac[i]=1LL*fac[i-1]*i%mod;
30 for(int i=2;i<N;i++)inv[i]=1LL*(mod-mod/i)*inv[mod%i]%mod;
31 for(int i=2;i<N;i++)inv[i]=1LL*inv[i-1]*inv[i]%mod;
32 for(int i=1;i<M;i++)mi[i]=3LL*mi[i-1]%mod;
33 scanf("%d%d%d",&n,&m,&k);
34 for(int i=0;i<M;i++)rev[i]=(rev[i>>1]>>1)+((i&1)*(M>>1));
35 for(int i=1;i<M;i<<=1)
36 for(int j=0;j<i;j++)w[i+j]=cd(cos(j*PI/i),sin(j*PI/i));
37 for(int i=0;i<=m;i++)a1[i]=cd(inv[i]/K,0);
38 for(int i=0;i<=m;i++)a2[i]=cd(inv[i]%K,0);
39 for(int i=0;i<=k;i++)b1[i]=cd(inv[i]/K,0);
40 for(int i=0;i<=k;i++)b2[i]=cd(inv[i]%K,0);
41 fft(a1,0);
42 fft(a2,0);
43 fft(b1,0);
44 fft(b2,0);
45 for(int i=0;i<M;i++){
46 c1[i]=a1[i]*b1[i];
47 c2[i]=a1[i]*b2[i]+a2[i]*b1[i];
48 c3[i]=a2[i]*b2[i];
49 }
50 fft(c1,1);
51 fft(c2,1);
52 fft(c3,1);
53 for(int i=0;i<=m+k;i++){
54 int s1=llround(c1[i].real())%mod;
55 int s2=llround(c2[i].real())%mod;
56 int s3=llround(c3[i].real())%mod;
57 int s=(1LL*K*K%mod*s1+1LL*K*s2+s3)%mod;
58 ans=(ans+1LL*fac[n+i-1]*mi[m+k-i]%mod*s)%mod;
59 }
60 ans=1LL*ans*inv[n-1]%mod;
61 printf("%d",ans);
62 }

事实上还有更好的做法,由于$\frac{1}{i!(s-i)!}=\frac{{s\choose i}}{s!}$,代入即$\frac{\sum_{s=0}^{m+k}s!(n+s-1)!3^{m+k-s}\sum_{0\le i\le m,0\le s-i\le k}{s\choose i}}{(n-1)!}$

考虑后者,也就是$\sum_{i=l}^{r}{s\choose i}$,定义为$f(s,l,r)$,我们将这一行的每一个数乘以2(即有2个),在将非首尾的数利用杨辉三角合并,即$2f(s,l,r)=f(s,l+1,r)+{s\choose l}+{s\choose r}$

利用这个式子,注意到每一次$s$增加区间两端点变化为为$o(1)$,就可以线性的完成,复杂度为$o(n)$

 1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 1000005
4 #define mod 1000000007
5 int n,m,k,ans,fac[N],inv[N],mi[N];
6 int c(int n,int m){
7 if (n<m)return 0;
8 return 1LL*fac[n]*inv[m]%mod*inv[n-m]%mod;
9 }
10 int main(){
11 fac[0]=inv[0]=inv[1]=mi[0]=1;
12 for(int i=1;i<N;i++)fac[i]=1LL*fac[i-1]*i%mod;
13 for(int i=2;i<N;i++)inv[i]=1LL*(mod-mod/i)*inv[mod%i]%mod;
14 for(int i=2;i<N;i++)inv[i]=1LL*inv[i-1]*inv[i]%mod;
15 for(int i=1;i<N;i++)mi[i]=3LL*mi[i-1]%mod;
16 scanf("%d%d%d",&n,&m,&k);
17 //l=max(s-k,0),r=min(m,s)
18 int s=1,l=0,r=0;
19 for(int i=0;i<=m+k;i++){
20 if (i){
21 s=((2*s%mod+mod-c(i-1,l))%mod+mod-c(i-1,r))%mod;
22 l++;
23 while (max(i-k,0)<l)s=(s+c(i,--l))%mod;
24 while (l<max(i-k,0))s=(s+c(i,l++))%mod;
25 while (r<min(m,i))s=(s+c(i,++r))%mod;
26 while (min(m,i)<r)s=(s+c(i,r--))%mod;
27 }
28 ans=(ans+1LL*fac[n+i-1]*mi[m+k-i]%mod*s%mod*inv[i])%mod;
29 }
30 ans=1LL*ans*inv[n-1]%mod;
31 printf("%d",ans);
32 }

[atARC061F]Card Game for Three的更多相关文章

  1. Lesson 3 Please send me a card

    Text Postcards always spoil my holidays. Last summer, I went to Italy. I visited museums and sat in ...

  2. iOS - Card Identification 银行卡号识别

    1.CardIO 识别 框架 GitHub 下载地址 配置 1.把框架整个拉进自己的工程,然后在 TARGETS => Build Phases => Link Binary With L ...

  3. HDOJ 4336 Card Collector

    容斥原理+状压 Card Collector Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/O ...

  4. Opensuse enable sound and mic card

    Install application pavucontrol Run pavucontrol You will see the configuration about sound card and ...

  5. 进监狱全攻略之 Mifare1 Card 破解

    补充新闻:程序员黑餐馆系统 给自己饭卡里充钱 ,技术是双刃剑,小心,小心! 前言 从M1卡的验证漏洞被发现到现今,破解设备层出不穷,所以快速傻瓜式一键破解不是本文的重点,年轻司机将从本文中获得如下技能 ...

  6. Card(bestcoder #26 B)

    Card Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submi ...

  7. [OpenJudge 3061]Flip The Card

    [OpenJudge 3061]Flip The Card 试题描述 There are N× Ncards, which form an N× Nmatrix. The cards can be p ...

  8. [杂谈]交通工具orca card

    How and Where to Use the ORCA Card The Microsoft ORCA card provides unlimited rides on all buses, tr ...

  9. [OrangePi] Backup internal EMMC to SD Card

    Boot your Orange PI board from EMMC without SD Card inserted login insert your SD Card Run: sudo ins ...

随机推荐

  1. netty 处理客户端连接

    Netty如何处理连接事件 上文讲了Netty如何绑定端口,现在我们来阅读下netty如何处理connect事件.上文我们说了NioEventLoop启动后不断去调用select的事件,当客户端连接时 ...

  2. 阿里云 Serverless 再升级,从体验上拉开差距

    差距都在细节上. Serverless 要成就云计算的下一个 10 年,不仅需要在技术上持续精进,也需要在产品体验上精耕细作. 近日,阿里云 Serverless 再度升级,发布了一系列围绕产品体验方 ...

  3. 题解 CF1119H Tripe题解

    题目传送门 题目大意 给出\(n,t,x,y,z\),值域\(\le 2^t\),给出\(n\)个三元组\((a_i,b_i,c_i)\),表示有\(x\)个\(a_i\),\(y\)个\(b_i\) ...

  4. bzoj4712 洪水(动态dp)

    看起来很模板的一个题啊 qwq 但是我还是wei 题目要求的是一个把根节点和所有叶子断开连接的最小花费. 还是想一个比较\(naive\)的做法 我们令\(dp1[i]\)表示,在\(i\)的子树内, ...

  5. 脚本注入1(boolean&&get)

    现在,我们回到之前,练习脚本支持的布尔盲注(get型). 布尔盲注的应用场景是查询成功和失败时回显不同,且存在注入点的地方. 这里以Less-8为例: 发现查询成功时,会显示:失败则无回显. 同时发现 ...

  6. JDBC:(java database Connection) java数据库连接。

    JDBC 指 Java 数据库连接,是一种标准Java应用编程接口( JAVA API),用来连接 Java 编程语言和广泛的数据库. JDBC连接步骤: 1.先导入jar包,把jar放入到工程下并 ...

  7. Scrum Meeting 0427

    零.说明 日期:2021-4-27 任务:简要汇报两日内已完成任务,计划后两日完成任务 一.进度情况 组员 负责 两日内已完成的任务 后两日计划完成的任务 qsy PM&前端 完成部分登录,注 ...

  8. 【二食堂】Alpha - Scrum Meeting 6

    Scrum Meeting 6 例会时间:4.16 11:40 - 12:10 进度情况 组员 昨日进度 今日任务 李健 1. 文本区域进度40%,UI需要进行调整issue 1. 继续文本区域的开发 ...

  9. 2021.9.9考试总结[NOIP模拟50]

    T1 第零题 神秘结论:从一个点满体力到另一个点的复活次数与倒过来相同. 于是预处理出每个点向上走第$2^i$个死亡点的位置,具体实现可以倍增或二分. 每次询问先从两个点同时向上倍增,都转到离$LCA ...

  10. 野指针和free总结超有用的资料

    在C语言项目中,经常会遇到需要程序员手动分配内存的地方.这样做能够节省大量的内存空间,也让程序更加灵活.只要你有一定的基础,那么肯定用过 malloc 或者 ralloc和free的组合.这个组合使用 ...