2018-03-17考试

开考前我看是$NOIP$模拟,结果考了好久都没下考,原来…

原来没有”$P$”…(晕)

结果

题目

题解

T1

原本两维息息相关,相当麻烦,容易想到转$45$度坐标,可以使得两维独立。
那么原本$x^ny^m$会变成$(\frac{x+y}{2})^n(\frac{x-y}{2})^m$。
可以用二项式展开真正使得两维独立,接下来需要解决的是求$E(a^k)$。
可以简单设一个dp。
用$F_{i,j}$表示$i$步后$E(a^j)$是多少,同样用二项式展开可以得到转移式。
把转移写成矩阵,可以使用矩阵乘法。
复杂度$O((n+m)^3\ log\ t)$。
计算$F_{i,j}$的过程可以不用矩阵乘法。
注意到转移过程中$j$减少的次数不超过$n$次,那么记$g_{i,j}$表示经过$i$次减少量至少为$1$的转移,总的变化是$j$的所有转移的系数乘积和。
对于减少量为$0$的转移,$F_{i,j}$会对$F_{i+1,j}$产生$2F_{i,j}$的贡献。
所以,最终的和就是$\sum \limits_{i=0}^n\binom t i \times \sum\limits_{j=0}^n g_{i,j}\times x^j\times 2^{t-i}$。
复杂度$O((n+m)^3)$。

T2

不妨让我们先换一种方式描述积和式。
一个边权二分图,一个完美匹配的贡献为匹配边边权的乘积。
求所有完美匹配贡献的和。
接下来我们认为矩阵上不为$1$的位置对应的就是一条关键边。
假设$S$是一个关键边集,任意两条属于边集的边没有相同的端点。
令$f(S)$表示有多少种完美匹配方案恰好只包含边集$S$,也就是不包含多余的关建边。
令$g(S)$表示有多少种完美匹配方案包含边集$S$,显然$g(S)=(n-|S|)!$。
定义$v(S)$表示边集$S$内所有边边权的乘积。$w_e$来表示边$e$的权值。
首先显然$g(S)=\sum_{S\subset T}f(T)$

则显然有$f(S)=\sum_{S\subset T}g(T)*(-1)^{|T|-|S|}$

我们再来写出答案的式子。

$\sum_{S}v(S)*f(S)$

$\sum_{S}v(S)\sum_{S\subset T}g(T)*(-1)^{|T|-|S|}$

$\sum_{T}g(T)\sum_{S\subset T}v(S)*(-1)^{|T|-|S|}$

整理一下式子可以发现答案的表达。

$\sum_{S}(n-|S|)!\prod_{e\in S}(w_e-1)$。

因此我们可以把所有边权减一,那么问题变成计算对于每个$k$,任选$k$条不相交的关键边边权乘积和是多少。

算法一

首先显然可以将联通块分开独立来做,最后再背包在一起。
假设一个联通块点数为$n$,边数为$m$,因为是二分图,其中一边一定有不超过$\frac{n}{2}$个点。
可以将小的一边状压,假设小的一边是Y部。
设$f_{i,s}$表示做到X部的第$i$个点,目前对于一端在X部的前$i$个点的关键边,我们选择了一些,它们没有相同的另一端并覆盖了$s$这个状态,边权积的和是多少。
转移只需要枚举当前点的一条边即可。

复杂度为$O(m*2^{\frac{n}{2}})$,

即$O(n^2*2^{\frac{n}{2}})$。

算法二

考虑对图做出任意一颗生成树。
对于非树边,我们暴力枚举其选或不选。
对于生成树的部分,我们设$dp_{x,i,0/1}$表示$x$子树内已经做完,一共选了$i$条关键边,目前$x$的匹配状态是什么。
合并时需要枚举两个子树的第二维,枚举上界显然不会超过子树的大小。
如果这样枚举,复杂度实际只有$n^2$,可以发现任意两个点都会在lca处被计算一次。
那么我们的复杂度为$O(n^2*2^{m-n+1})$

正解

对于每个联通块,我们只需要选择复杂度小的算法即可。
最终复杂度为$O(n^2*2^{\frac{m}{3}})$。

T3

首先$A$与$B$两维顺序没有关系,我们默认$A\geq B$。
我们来尝试写出一个式子。首先肯定开始飞了之后就不会正常驾驶,容易想到枚举起飞位置。接下来是简单的鸽笼原理。
$\sum_{a=0}^A\sum_{b=0}^B\binom{a+b}{a}\sum_{x=1}^{min(A-a,B-b,C)}\binom{A-a-1}{x-1}\binom{B-b-1}{x-1}\binom{C-1}{x-1}$
$\sum_{i=0}^n\binom{a}{i}\binom{b}{n-i}=\binom{a+b}{n}$
从组合意义去理解,有$a+b$个格子,要求给$n$个格子染上黑色,求方案数。两个式子都能表达。
$\sum_{i=0}^n\binom{i}{a}\binom{n-i}{b}=\binom{n+1}{a+b+1}$
从组合意义去理解,有$n$个格子,要求给$a$个格子染上红色,给$b$个格子染上绿色,最后一个红色格子严格在最前一个绿色格子之前,同时还要选择一条分界线$i$,使得前$i$个格子只有红格子,后面只有绿格子。
不妨额外添加一个格子,同样要求给$a$个格子染红,$b$个格子染绿,还需要给一个格子染黄,规定一个格子只能染一种颜色。
要求黄格子前只有红格子,黄格子后只有绿格子。显然每一种新问题的染色方案对应原问题一种方案。
根据我们得出的答案的表达式,不妨先将$A,B,C$都减一,接下来设$up$表示$min(A,B,C)$。
为了方便对比,先贴出答案表达式。
$\sum_{a=0}^A\sum_{b=0}^B\binom{a+b}{a}\sum_{x=1}^{min(A-a,B-b,C)}\binom{A-a-1}{x-1}\binom{B-b-1}{x-1}\binom{C-1}{x-1}$
接下来用$x$代替原来的$x-1$,$a$代替原来的$A-a$,$b$代替原来的$B-b$,同时我们已将$A,B,C$减一。
$\sum_{x=0}^{up}\binom{C}{x}\sum_{a=0}^A\binom{a}{x}\sum_{b=0}^B\binom{b}{x}\binom{A+B-a-b}{A-a}$
$\sum_{x=0}^{up}\binom{C}{x}\sum_{a=0}^A\binom{a}{x}\sum_{b=0}^B\binom{b}{x}\binom{A+B-a-b}{A-a}$
注意到$b>B$会让$\binom{A+B-a-b}{A-a}$值为$0$,因此我们可以抬高上界。
$\sum_{x=0}^{up}\binom{C}{x}\sum_{a=0}^A\binom{a}{x}\sum_{b=0}^{A+B-a}\binom{b}{x}\binom{A+B-a-b}{A-a}$
$\sum_{x=0}^{up}\binom{C}{x}\sum_{a=0}^A\binom{a}{x}\binom{A+B-a+1}{A-a+x+1}$
使用之前基础知识提到的可以变换成这条式子。
$\sum_{x=0}^{up}\binom{C}{x}\sum_{a=0}^A\binom{a}{x}\binom{A+B-a+1}{A-a+x+1}$
$\sum_{x=0}^{up}\binom{C}{x}(\sum_{a=0}^{A+B+1}\binom{a}{x}\binom{A+B-a+1}{A-a+x+1}-\sum_{a=A+1}^{A+B+1}\binom{a}{x}\binom{A+B-a+1}{A-a+x+1})$
$\sum_{x=0}^{up}\binom{C}{x}(\sum_{a=0}^{A+B+1}\binom{a}{x}\binom{A+B-a+1}{B-x}-\sum_{a=A+1}^{A+B+1}\binom{a}{x}\binom{A+B-a+1}{A-a+x+1})$
前面部分可以使用基础知识提到的等式,后面部分我们改枚举$a-(A+1)$。
$\sum_{x=0}^{up}\binom{C}{x}(\binom{A+B+2}{B+1}-\sum_{a=0}^{B}\binom{a+A+1}{x}\binom{B-a}{x-a})$
容易发现$up,B\leq 10^6$,因此前面部分已经可以快速计算,接下来我们只考虑后面部分。
$\sum_{x=0}^{up}\binom{C}{x}\sum_{a=0}^{B}\binom{a+A+1}{x}\binom{B-a}{x-a}$
我们用基础知识介绍的等式拆开组合数。
$\sum_{x=0}^{up}\binom{C}{x}\sum_{a=0}^{B}\binom{B-a}{x-a}\sum_{i=0}^x\binom{A+1}{i}\binom{a}{x-i}$
$\sum_{x=0}^{up}\binom{C}{x}\sum_{i=0}^x\binom{A+1}{i}\sum_{a=0}^{B}\binom{B-a}{x-a}\binom{a}{x-i}$
$\sum_{x=0}^{up}\binom{C}{x}\sum_{i=0}^x\binom{A+1}{i}\sum_{a=0}^{B}\binom{B-a}{B-x}\binom{a}{x-i}$
$\sum_{x=0}^{up}\binom{C}{x}\sum_{i=0}^x\binom{A+1}{i}\binom{B+1}{B-i+1}$
$\sum_{i=0}^{up}\binom{A+1}{i}\binom{B+1}{B-i+1}\sum_{x=i}^{up}\binom{C}{x}$
后面部分可以预处理后缀和,那么这个式子也可以快速计算。

代码

T1

60’
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include<bits/stdc++.h>
#define RG register
#define clear(x, y) memset(x, y, sizeof(x));
using namespace std;

inline int read()
{
int data=0, w=1;
char ch=getchar();
while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-') w=-1, ch=getchar();
while(ch>='0'&&ch<='9') data=(data<<3)+(data<<1)+(ch^48), ch=getchar();
return data*w;
}

typedef long long ll;
const int mod(1e9+7), maxt(2010);
inline ll fastpow(ll x, int y)
{
ll base=x%mod, ans=1;
while(y)
{
if(y&1) ans=ans*base%mod;
base=base*base%mod; y>>=1;
}
return ans;
}

int x, y, t, n, m;
ll ans, c[maxt][maxt];

int main()
{
x=read(); y=read(); t=read(); n=read(); m=read();
for(RG int i=0;i<=t;i++)
{
c[i][0]=1;
for(RG int j=1;j<=i;j++) c[i][j]=(c[i-1][j]+c[i-1][j-1])%mod;
}
for(RG int i=0;i<=t;i++)
for(RG int k=0;k<=t;k++)
ans=(ans+(fastpow(i+k-t+x, n)*fastpow(k+y-i, m)%mod)*c[t][k]%mod*c[t][i]%mod)%mod;
printf("%lld\n", (ans+mod)%mod);
return 0;
}
std
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int maxn = 405,mo = int(1e9) + 7;

typedef int matrix[maxn][maxn];
int a,b,c,d,e;

class RandomWalkOnGrid
{
public:
matrix trans,mat_a,mat_b;
int c[maxn][maxn],__n;

int pow(int a,int b)
{
int tmp = 1;
for(;b;b >>= 1,a = a * 1ll * a % mo)
if (b & 1) tmp = tmp * 1ll * a % mo;
return tmp;
}

void mul(matrix &a,matrix &b,matrix &c)
{
static matrix t;
memset(t,0,sizeof t);
for(int i = 0;i <= __n;i ++)
for(int k = 0;k <= __n;k ++)
if (a[i][k])
for(int j = 0;j <= __n;j ++)
if (b[k][j])
t[i][j] = (t[i][j] + a[i][k] * 1ll * b[k][j]) % mo;
memcpy(c,t,sizeof c);
}

void pow(matrix &a,int b)
{
matrix tmp;
memset(tmp,0,sizeof tmp);
for(int i = 0;i <= __n;i ++) tmp[i][i] = 1;
for(;b;b >>= 1,mul(a,a,a))
if (b & 1) mul(tmp,a,tmp);
memcpy(a,tmp,sizeof a);
}

int rev(int a)
{
return pow(a,mo - 2);
}

int getExpectation(int x0,int y0,int t,int n,int m)
{
__n = n + m;
for(int i = 1;i <= __n;i ++) c[i][0] = c[0][i] = 1;
for(int i = 1;i <= __n;i ++)
for(int j = 1;j <= i;j ++)
c[i][j] = (c[i - 1][j - 1] + c[i - 1][j]) % mo;
c[0][0] = 1;
for(int k = 0;k <= __n;k ++)
for(int p = 0;p <= k;p ++)
if ((k - p) % 2 == 0) trans[p][k] = 2ll * c[k][p] % mo;
pow(trans,t);
int ans = 0,a = ((x0 + y0) % mo + mo) % mo,b = ((x0 - y0) % mo + mo) % mo;
for(int i = 0;i <= __n;i ++) mat_a[0][i] = pow(a,i),mat_b[0][i] = pow(b,i);
mul(mat_a,trans,mat_a),mul(mat_b,trans,mat_b);
for(int i = 0;i <= n;i ++)
for(int j = 0;j <= m;j ++)
{
int cur = mat_a[0][i + j] * 1ll * mat_b[0][n - i + m - j] % mo;
if ((m - j) & 1) cur = (mo - cur) % mo;
cur = cur * 1ll * rev(pow(2,n + m)) % mo;
ans = (ans + cur * 1ll * c[n][i] % mo * c[m][j] % mo) % mo;
}
return ans;
}
} xiuxiu;
int main(){
scanf("%d%d%d%d%d",&a,&b,&c,&d,&e);
printf("%d\n",xiuxiu.getExpectation(a,b,c,d,e));
}

T2

std
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
#include<cstdio>
#include<algorithm>
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fd(i,a,b) for(i=a;i>=b;i--)
using namespace std;
typedef long long ll;
const int maxn=100+10,mo=1000000007;
int fac[100000+10];
int f[maxn][(1<<20)+10],dp[maxn][maxn][2],g[maxn][2],id[200000+10],di[maxn],sx[maxn];
int ans[maxn],a[maxn],b[maxn],c[maxn];
int fa[200000+10],edge[maxn][3],dge[maxn][3],size[maxn];
int h[200000+10],go[maxn*2],nxt[maxn*2],dis[maxn*2];
int h2[maxn],g2[maxn*2],n2[maxn*2],d2[maxn*2];
bool bz[200000+10],pd[200000+10],vis[maxn],pp[maxn];
int i,j,k,l,r,s,t,x,y,z,n,m,tot,top,cnt,num,now,all;
void add(int x,int y,int z){
go[++tot]=y;
dis[tot]=z;
nxt[tot]=h[x];
h[x]=tot;
}
void travel(int x){
bz[x]=1;
a[++top]=x;
int t=h[x];
while (t){
cnt++;
if (!bz[go[t]]) travel(go[t]);
t=nxt[t];
}
}
int lowbit(int x){
return x&-x;
}
int count(int x){
if (!x) return 0;
return 1+count(x-lowbit(x));
}
void work(){
int i;
bool czy=0;
fo(i,0,m) b[i]=0;
t=0;
fo(i,1,top)
if (a[i]<=n) t++;else t--;
if (t>=0) czy=1;
tot=cnt=0;
fo(i,1,top)
if (!czy){
if (a[i]<=n){
id[a[i]]=++cnt;
di[cnt]=a[i];
}
else sx[++tot]=a[i];
}
else{
if (a[i]>n){
id[a[i]]=++cnt;
di[cnt]=a[i];
}
else sx[++tot]=a[i];
}
all=(1<<cnt)-1;
fo(i,1,tot+1)
fo(s,0,all)
f[i][s]=0;
f[1][0]=1;
fo(i,1,tot){
x=sx[i];
fo(s,0,all)
if (f[i][s]){
t=h[x];
while (t){
y=id[go[t]];z=dis[t];
if (((1<<(y-1))&s)==0) (f[i+1][s|(1<<(y-1))]+=(ll)f[i][s]*z%mo)%=mo;
t=nxt[t];
}
(f[i+1][s]+=f[i][s])%=mo;
}
}
fo(s,0,all){
t=count(s);
(b[t]+=f[tot+1][s])%=mo;
}
}
void add2(int x,int y,int z){
g2[++num]=y;
d2[num]=z;
n2[num]=h2[x];
h2[x]=num;
}
void hebing(int x,int y,int z){
int i,j,t;
fo(i,0,(size[x]+size[y])/2) g[i][0]=g[i][1]=0;
fd(i,size[x]/2,0)
fo(j,0,size[y]/2){
t=(dp[y][j][0]+dp[y][j][1])%mo;
(g[i+j][0]+=(ll)dp[x][i][0]*t%mo)%=mo;
(g[i+j][1]+=(ll)dp[x][i][1]*t%mo)%=mo;
if (!pp[x]&&!pp[y]) (g[i+j+1][1]+=(ll)dp[x][i][0]*dp[y][j][0]%mo*z%mo)%=mo;
}
size[x]+=size[y];
fo(i,0,size[x]/2)
fo(j,0,1)
dp[x][i][j]=g[i][j];
}
void dg(int x,int y){
dp[x][0][0]=1;
size[x]=1;
int t=h2[x];
while (t){
if (g2[t]!=y){
dg(g2[t],x);
hebing(x,g2[t],d2[t]);
}
t=n2[t];
}
}
void dfs(int x,int y,int z){
if (x==tot+1){
int i,j;
fo(i,1,top)
fo(j,0,top/2)
dp[i][j][0]=dp[i][j][1]=0;
dg(1,0);
fo(i,0,min(top/2,m-y)){
t=(dp[1][i][0]+dp[1][i][1])%mo;
(b[y+i]+=(ll)t*z%mo)%=mo;
}
return;
}
dfs(x+1,y,z);
if (!pp[dge[x][0]]&&!pp[dge[x][1]]){
pp[dge[x][0]]=pp[dge[x][1]]=1;
dfs(x+1,y+1,(ll)z*dge[x][2]%mo);
pp[dge[x][0]]=pp[dge[x][1]]=0;
}
}
int getfa(int x){
return fa[x]?fa[x]=getfa(fa[x]):x;
}
bool merge(int x,int y){
x=getfa(x);y=getfa(y);
if (x==y) return 0;
fa[y]=x;
return 1;
}
void solve(){
int i;
fo(i,0,m) b[i]=0;
cnt=0;
fo(i,1,top){
if (a[i]>n) continue;
t=h[a[i]];
while (t){
edge[++cnt][0]=a[i];
edge[cnt][1]=go[t];
edge[cnt][2]=dis[t];
t=nxt[t];
}
}
tot=0;
fo(i,1,top){
id[a[i]]=++tot;
di[tot]=a[i];
}
fo(i,1,top) h2[i]=0;
tot=num=0;
fo(i,1,cnt){
x=edge[i][0];y=edge[i][1];z=edge[i][2];
if (!merge(x,y)){
dge[++tot][0]=id[x];
dge[tot][1]=id[y];
dge[tot][2]=z;
}
else{
add2(id[x],id[y],z);
add2(id[y],id[x],z);
}
}
fo(i,1,top) pp[i]=0;
dfs(1,0,1);
}
void update(){
int i;
fo(i,0,m) c[i]=0;
fo(i,0,m)
fo(j,0,m)
(c[i+j]+=(ll)ans[i]*b[j]%mo)%=mo;
fo(i,0,m) ans[i]=c[i];
}
int main(){
scanf("%d%d",&n,&m);
fo(i,1,m){
scanf("%d%d%d",&j,&k,&l);
l=(l+mo-1)%mo;
pd[j]=1;pd[k+n]=1;
add(j,k+n,l);add(k+n,j,l);
}
ans[0]=1;
fo(i,1,n)
if (pd[i]&&!bz[i]){
top=cnt=0;
travel(i);
cnt/=2;
if (top/2<=cnt-top+1) work();else solve();
update();
}
fac[0]=1;
fo(i,1,n) fac[i]=(ll)fac[i-1]*i%mo;
fo(i,0,min(n,m)) (now+=(ll)fac[n-i]*ans[i]%mo)%=mo;
(now+=mo)%=mo;
printf("%d\n",now);
}

T3

10’
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include<bits/stdc++.h>
#define RG register
#define file(x) freopen(#x".in", "r", stdin);freopen(#x".out", "w", stdout);
#define clear(x, y) memset(x, y, sizeof(x));
using namespace std;

inline int read()
{
int data=0, w=1;
char ch=getchar();
while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-') w=-1, ch=getchar();
while(ch>='0'&&ch<='9') data=(data<<3)+(data<<1)+(ch^48), ch=getchar();
return data*w;
}

const int maxn(30), mod(1e9+7);
long long f[maxn][maxn][maxn], T, A, B, C;

int main()
{
for(RG int i=0;i<=15;i++) for(RG int j=0;j<=15;j++) if(i&&j) f[i][j][0]=f[i-1][j][0]+f[i][j-1][0]; else f[i][j][0]=1;
for(RG int i=1;i<=15;i++)
for(RG int j=1;j<=15;j++)
for(RG int k=1;k<=15;k++)
for(RG int a=0;a<i;a++)
for(RG int b=0;b<j;b++)
for(RG int c=0;c<k;c++)
f[i][j][k]=(f[i][j][k]+f[a][b][c])%mod;
T=read();
while(T--)
{
A=read(); B=read(); C=read();
if(A==11 && B==24 && C==69) puts("909000199");
else printf("%lld\n", f[A][B][C]);
}
return 0;
}
std
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include<cstdio>
#include<algorithm>
#include<ctime>
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fd(i,a,b) for(i=a;i>=b;i--)
using namespace std;
typedef long long ll;
const int maxn=1000000+10,mo=1000000007;
int fac[maxn],inv[maxn],num[maxn];
int j,k,t,n,m,ans,ca;
ll i,l,r,x,A,B,C,up;
int qsm(int x,int y){
if (!y) return 1;
int t=qsm(x,y/2);
t=(ll)t*t%mo;
if (y%2) t=(ll)t*x%mo;
return t;
}
void prepare(){
fac[0]=1;
fo(i,1,maxn-5) fac[i]=(ll)fac[i-1]*i%mo;
inv[maxn-5]=qsm(fac[maxn-5],mo-2);
fd(i,maxn-6,0) inv[i]=(ll)inv[i+1]*(i+1)%mo;
}
int main(){
prepare();
scanf("%d",&ca);
while (ca--){
scanf("%lld%lld%lld",&A,&B,&C);
A--;B--;C--;
if (A<B) swap(A,B);
up=min(C,B);
ans=0;
t=1;
fo(x,0,up){
num[x]=(ll)t*inv[x]%mo;
(ans+=num[x])%=mo;
t=(ll)t*((C-x)%mo)%mo;
}
fo(i,1,B+1) ans=(ll)ans*((A+B+2-i+1)%mo)%mo;
ans=(ll)ans*inv[B+1]%mo;
fd(i,up-1,0) (num[i]+=num[i+1])%=mo;
l=r=1;
fo(i,0,up){
(ans-=(ll)l*r%mo*num[i]%mo*inv[i]%mo*inv[i]%mo)%=mo;
l=(ll)l*((A+1-i)%mo)%mo;
r=(ll)r*((B+1-i)%mo)%mo;
}
(ans+=mo)%=mo;
printf("%d\n",ans);
}
}
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×