B-Cannon
首先nnn个炮在一行操作一次的方案数为2(n−2)2(n-2)2(n−2):前面两个炮只能向右吃,最后两个跑只能向左吃,而其余的炮既可以向左也可以向右,于是有4+2(n−4)4+2(n-4)4+2(n−4)种
于是操作mmm次的操作排列的方案数为2m(n−2)(n−3)...(n−m−1)=2m(n−2)!(n−2−m)!2^m(n-2)(n-3)...(n-m-1)=2^m\frac {(n-2)!}{(n-2-m)!}2m(n−2)(n−3)...(n−m−1)=2m(n−2−m)!(n−2)!
设n=a−2,m=b−2n=a-2,m=b-2n=a−2,m=b−2
首先选择从kkk选择iii次操作第一行,选择k−ik-ik−i次操作第二行,而问题一还需要从kkk个位置选择出iii个按序放置操作序列,而问题二必须强制第一行操作放置在第二行操作前面,由此有:
对于问题1即是求
∑0≤i≤k(ki){2in!(n−i)!}×{2k−im![m−(k−i)]!}=2k∑0≤i≤kk!i!(k−i)!⋅n!(n−i)!⋅m![m−(k−i)]!=2kk!∑0≤i≤k(ni)(mk−i)=2kk!(n+mk)\begin{aligned} &\sum_{0\leq i\leq k}\dbinom{k}{i}\{2^i\frac{n!}{(n-i)!}\}×\{2^{k-i}\frac{m!}{[m-(k-i)]!}\}\\ \\&=2^k\sum_{0\leq i\leq k}\frac{k!}{i!(k-i)!}·\frac{n!}{(n-i)!}·\frac{m!}{[m-(k-i)]!}\\ \\&=2^kk!\sum_{0\leq i\leq k} \dbinom{n}{i}\dbinom{m}{k-i}\\\\&=2^kk!\dbinom{n+m}{k} \end{aligned}0≤i≤k∑(ik){2i(n−i)!n!}×{2k−i[m−(k−i)]!m!}=2k0≤i≤k∑i!(k−i)!k!⋅(n−i)!n!⋅[m−(k−i)]!m!=2kk!0≤i≤k∑(in)(k−im)=2kk!(kn+m)
对于问题2即是求
∑0≤i≤k{2in!(n−i)!}×{2k−im![m−(k−i)]!}=2k∑0≤i≤kn!(n−i)!×m![m−(k−i)]!=2kn!m!(n+m−k)!∑0≤i≤k(n+m−k)!(n−i)![m−(k−i)]!=2kn!m!(n+m−k)!∑0≤i≤k(n+m−kn−i)=2kn!m!(n+m−k)!∑n−k≤i≤n(n+m−kj)\begin{aligned} &\sum_{0\leq i\leq k}\{2^i\frac{n!}{(n-i)!}\}×\{2^{k-i}\frac{m!}{[m-(k-i)]!}\}\\\\&=2^k\sum_{0\leq i\leq k}\frac{n!}{(n-i)!}×\frac{m!}{[m-(k-i)]!}\\\\&=2^k\frac{n!m!}{(n+m-k)!}\sum_{0\leq i\leq k}\frac{(n+m-k)!}{(n-i)![m-(k-i)]!}\\\\&=2^k\frac{n!m!}{(n+m-k)!}\sum_{0\leq i\leq k}\dbinom{n+m-k}{n-i}\\\\&=2^k\frac{n!m!}{(n+m-k)!}\sum_{n-k\leq i\leq n}\dbinom{n+m-k}{j} \end{aligned}0≤i≤k∑{2i(n−i)!n!}×{2k−i[m−(k−i)]!m!}=2k0≤i≤k∑(n−i)!n!×[m−(k−i)]!m!=2k(n+m−k)!n!m!0≤i≤k∑(n−i)![m−(k−i)]!(n+m−k)!=2k(n+m−k)!n!m!0≤i≤k∑(n−in+m−k)=2k(n+m−k)!n!m!n−k≤i≤n∑(jn+m−k)
其中下面一项是组合数种的连续多项之和,考虑前缀和!
∑n−k≤j≤n(n+m−kj)=∑0≤j≤n(n+m−kj)−∑0≤j≤n−k−1(n+m−kj)=∑0≤j≤n(n+m−kj)−∑0≤j≤n−k−1(n+m−kn+m−k−j)=∑0≤j≤n(n+m−kj)−∑m+1≤j≤n+m−k(n+m−kj)=∑0≤j≤n(n+m−kj)−{∑0≤j≤n+m−k(n+m−kj)−∑0≤j≤m(n+m−kj)}=∑0≤j≤n(n+m−kj)+∑0≤j≤m(n+m−kj)−2n+m−k=sum(n+m−k)\begin{aligned} &\sum_{n-k\leq j\leq n}\dbinom{n+m-k}{j}\\\\&=\sum_{0\leq j\leq n}\dbinom{n+m-k}{j}-\sum_{0\leq j\leq n-k-1}\dbinom{n+m-k}{j}\\\\&=\sum_{0\leq j\leq n}\dbinom{n+m-k}{j}-\sum_{0\leq j\leq n-k-1}\dbinom{n+m-k}{n+m-k-j}\\\\&=\sum_{0\leq j\leq n}\dbinom{n+m-k}{j}-\sum_{m+1\leq j\leq n+m-k}\dbinom{n+m-k}{j}\\\\&=\sum_{0\leq j\leq n}\dbinom{n+m-k}{j}-\{\sum_{0\leq j\leq n+m-k}\dbinom{n+m-k}{j}-\sum_{0\leq j\leq m}\dbinom{n+m-k}{j}\}\\\\&=\sum_{0\leq j\leq n}\dbinom{n+m-k}{j}+\sum_{0\leq j\leq m}\dbinom{n+m-k}{j}-2^{n+m-k}=\text{sum}(n+m-k) \end{aligned}n−k≤j≤n∑(jn+m−k)=0≤j≤n∑(jn+m−k)−0≤j≤n−k−1∑(jn+m−k)=0≤j≤n∑(jn+m−k)−0≤j≤n−k−1∑(n+m−k−jn+m−k)=0≤j≤n∑(jn+m−k)−m+1≤j≤n+m−k∑(jn+m−k)=0≤j≤n∑(jn+m−k)−{0≤j≤n+m−k∑(jn+m−k)−0≤j≤m∑(jn+m−k)}=0≤j≤n∑(jn+m−k)+0≤j≤m∑(jn+m−k)−2n+m−k=sum(n+m−k)
考虑求出Sn,m=∑i=0m(ni)S_{n,m}=\sum_{i=0}^{m}\dbinom{n}{i}Sn,m=∑i=0m(in)的关于nnn的递推式
Sn,m=∑i=0m(ni)=∑i=0m[(n−1i)+(n−1i−1)]=Sn−1,m+Sn−1,m−1\begin{aligned} S_{n,m}=\sum_{i=0}^{m}\dbinom{n}{i}&=\sum_{i=0}^{m}[\dbinom{n-1}{i}+\dbinom{n-1}{i-1}]\\&=S_{n-1,m}+S_{n-1,m-1} \end{aligned}Sn,m=i=0∑m(in)=i=0∑m[(in−1)+(i−1n−1)]=Sn−1,m+Sn−1,m−1
而Sn−1,m=∑i=0m(n−1i)=Sn−1,m−1+(n−1m)\begin{aligned} S_{n-1,m}=\sum_{i=0}^{m}\dbinom{n-1}{i}&=S_{n-1,m-1}+\dbinom{n-1}{m} \end{aligned}Sn−1,m=i=0∑m(in−1)=Sn−1,m−1+(mn−1)
带入可得出
Sn,m=2Sn−1,m−(n−1m)S_{n,m}=2S_{n-1,m}-\dbinom{n-1}{m} Sn,m=2Sn−1,m−(mn−1)
由此可得出
sum(x)=∑0≤j≤n(xj)+∑0≤j≤m(xj)−2x=Sx,n+Sx,m−2x=2sum(x−1)−(x−1n)−(x−1m)\begin{aligned} \text{sum}(x)&=\sum_{0\leq j\leq n}\dbinom{x}{j}+\sum_{0\leq j\leq m}\dbinom{x}{j}-2^{x}\\\\&=S_{x,n}+S_{x,m}-2^x\\\\&=2\text{sum}(x-1)-\dbinom{x-1}{n}-\dbinom{x-1}{m} \end{aligned}sum(x)=0≤j≤n∑(jx)+0≤j≤m∑(jx)−2x=Sx,n+Sx,m−2x=2sum(x−1)−(nx−1)−(mx−1)
Code
#include<bits/stdc++.h>
using namespace std;
using ll=long long;
template <class T=int> T rd()
{T res=0;T fg=1;char ch=getchar();while(!isdigit(ch)) {if(ch=='-') fg=-1;ch=getchar();}while( isdigit(ch)) res=(res<<1)+(res<<3)+(ch^48),ch=getchar();return res*fg;
}
const ll mod=1e9+9;
ll qmi(ll a,ll b)
{ll v=1;while(b){if(b&1) v=v*a%mod;b>>=1;a=a*a%mod;}return v;
}
int n,m;
ll inv[10000010];
void solve1()
{ll ans=1;ll Two=1,Fact=1;ll C=1;for(int i=1;i<=n+m;i++){Two=Two*2%mod;Fact=Fact*i%mod;C=C*(n+m-i+1)%mod*inv[i]%mod;ans^=((Two*Fact%mod*C%mod)+mod)%mod;}printf("%lld ",ans);
}
ll sum[10000010];void solve2()
{ll Cn=1,Cm=1;sum[0]=1;for(int i=1;i<=min(n,m);i++) sum[i]=2*sum[i-1]%mod;for(int i=min(n,m)+1;i<=n+m;i++){sum[i]=2*sum[i-1]-(i>n?Cn:0)-(i>m?Cm:0);if(i>n) Cn=Cn*i%mod*inv[i-n]%mod;if(i>m) Cm=Cm*i%mod*inv[i-m]%mod;sum[i]=(sum[i]%mod+mod)%mod;}ll Factn=1,Factm=1,Two=1;for(int i=1;i<=n;i++) Factn=Factn*i%mod;for(int i=1;i<=m;i++) Factm=Factm*i%mod;ll Inv=1;for(int i=1;i<=n+m;i++) Inv=Inv*inv[i]%mod;ll ans=Two*Factn%mod*Factm%mod*Inv%mod*sum[n+m]%mod;for(int i=1;i<=n+m;i++){Two=Two*2%mod;Inv=Inv*(n+m-i+1)%mod;ans^=((Two*Factn%mod*Factm%mod*Inv%mod*sum[n+m-i]%mod)+mod)%mod;}printf("%lld\n",ans);
}
int main()
{n=rd()-2,m=rd()-2;inv[1]=1;for(int i=2;i<=n+m;i++) inv[i]=(mod-mod/i*inv[mod%i]%mod)%mod;solve1();solve2();return 0;
}
看着公式写代码都写了好长时间,wtcl