#莫队,排列组合,容斥原理,卡特兰数#洛谷 4260 [Code+#3] 博弈论与概率统计
分析
由于赢的场数是固定的,所以概率并没有用,要想得分足够高,那就应该先输后赢
设输的场次为 -1,赢的场次为 1,得分前缀和为 ,那么得分就是
如果将输视为向上移,将赢视为向右移,那么恰好得到某个最小前缀和为 的方案数
相当于恰好碰到 又不能碰到 的方案数,那么将 对称到
容斥一下就是 乘上得分
由于得分不能为负值,所以分 和 两类讨论
对于第一类情况,相当于求解
将两项分开计算得到答案为
对于第二类情况,相当于求解
将两项分开计算得到答案为
最后答案都除以 就可以得到期望得分
设 ,则
所以对于后面的和式可以根据 的增减计算,用莫队解决
代码
#include <cstdio>
#include <cctype>
#include <algorithm>
using namespace std;
const int mod=1000000007,N=250011;
struct rec{int n,m,rk;}q[N];
int pos[N],fac[N],inv[N],ans[N],Q;
int iut(){
int ans=0,f=1; char c=getchar();
while (!isdigit(c)) f=(c=='-')?-f:f,c=getchar();
while (isdigit(c)) ans=ans*10+c-48,c=getchar();
return ans*f;
}
void print(int ans){
if (ans>9) print(ans/10);
putchar(ans%10+48);
}
bool cmp(rec x,rec y){
if (pos[x.n]!=pos[y.n]) return pos[x.n]<pos[y.n];
return (pos[x.n]&1)?(x.m<y.m):(x.m>y.m);
}
void Mo(int &x,int y){x=x+y>=mod?x+y-mod:x+y;}
int C(int n,int m){
if (n<m) return 0;
return 1ll*fac[n]*inv[m]%mod*inv[n-m]%mod;
}
int main(){
fac[0]=fac[1]=inv[0]=inv[1]=1;
for (int i=2;i<N;++i) inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod,pos[i]=i/500;
for (int i=2;i<N;++i) fac[i]=1ll*fac[i-1]*i%mod,inv[i]=1ll*inv[i-1]*inv[i]%mod;
Q=iut(),iut();
for (int i=1;i<=Q;++i){
int n=iut(),m=iut();
if (n>m) ans[i]=n-m,q[i]=(rec){n+m,m-1,i};
else q[i]=(rec){n+m,n-1,i};
}
sort(q+1,q+1+Q,cmp);
int n=0,m=0,now=1;
for (int i=1;i<=Q;++i){
int t=1ll*inv[q[i].n]*fac[q[i].m+1]%mod*fac[q[i].n-q[i].m-1]%mod;
while (n>q[i].n) Mo(now,C(--n,m)),now=500000004ll*now%mod;
while (n<q[i].n) Mo(now,now),Mo(now,mod-C(n++,m));
while (m<q[i].m) Mo(now,C(n,++m));
while (m>q[i].m) Mo(now,mod-C(n,m--));
Mo(ans[q[i].rk],1ll*now*t%mod);
}
for (int i=1;i<=Q;++i) print(ans[i]),putchar(10);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 张高兴的大模型开发实战:(一)使用 Selenium 进行网页爬虫
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构