Fun fact: For all AGC problems with score>=1600 this year, the number of accepted solutions is no more than 1. --Retired_MiFaFaOvO
A. Three Cells per Row and Column
- 將 \(n \times n\) 的方格黑白染色,使其滿足:
- 每行每列均恰有 \(3\) 個黑格。
- 整個圖中恰有 \(n\) 個黑色四聯通塊。
- \(6 \leq n \leq 500\)。
最簡單構造題?
不考慮第二個限制,可以這樣染:
#.....##
##.....#
###.....
.###....
...###..
....###.
.....###
對於第二個限制,考慮換一下行的順序。
可以想到讓每一行都形成一個聯通塊(前兩行共同組成 \(2\) 個聯通塊),所以就是:
#.....##
##.....#
..###...
.....###
.###....
....###.
###.....
...###..
\(n=6\) 或 \(n=7\) 時會有點小問題,實測把第 \(2\) 行和第 \(4\) 行換一下即可。
代碼里是按列寫的。
#include<bits/stdc++.h>
using namespace std;
const int N=550;
int n,ans[N][N];
int main(){
cin>>n;
ans[1][1]=ans[1][2]=ans[2][2]=1;
ans[n][1]=ans[n][2]=ans[n-1][1]=1;
int nw=2;
for(int st=3;st>=1;st--){
for(int x=st;x+2<=n;x+=3){
nw++;
ans[x][nw]=ans[x+1][nw]=ans[x+2][nw]=1;
}
}
if(n==6 || n==7){
for(int i=1;i<=n;i++) swap(ans[i][2],ans[i][4]);
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(ans[i][j]) putchar('#');
else putchar('.');
}
putchar('\n');
}
}
B. Range Argmax
- 給定 \(M\) 個區間 \(\{(L_i,R_i)\}\)。求長度為 \(M\) 的數組 \(x_1,x_2,\cdots,x_m\) 的數量,滿足:
- 存在長度為 \(N\) 的排列 \(p_1,\cdots,p_N\),滿足 \(\forall i, p_{x_i}=\max\limits_{j=L_i}^{R_i} \{p_j\}\)。
- 答案對 \(998244353\) 取模。
- \(2 \leq N \leq 300\),\(1 \leq M \leq N(N-1)/2\),\(1 \leq L_i < R_i \leq N\),所有區間互不相同。
場上想了兩小時沒整出來
考慮直接數 \(x\),要求等價於若 \(i\) 和 \(j\) 區間分別選了 \(a\) 和 \(b\) 作為最大值且 \(a,b \in [L_i,R_i] \wedge [L_j,R_j]\),那么 \(a=b\)。然后就不會了
轉換思路,考慮數 \(p\),但是為了避免算重我們讓一個 \(x\) 只對應一個 \(p\)。
考慮怎樣由 \(x\) 構造一個 \(p\),可以從大到小插入每個值,將其插入能插入的 最左端 的位置。
這樣構造並沒有什么性質能夠快速判斷 \(x\) 能否生成 \(p\)。但是我們發現每次插入一個值后,跨過該位置的區間的最大值已經被定下來了,而左右區間是獨立的,可以考慮區間 DP。
對於區間 \([l,r]\),枚舉它的最大值位置為 \(k\),即將它分成了 \([l,k)\) 和 \((k,r]\) 兩部分。然而,為了確保不算重,我們需要保證 \(k\) 不能放在更左邊的位置:
- 對於右邊的區間,沒有限制
- 對於左邊的區間,若左邊的區間選擇了 \(t\),那么必須有一個區間同時包含 \(t\) 與 \(k\),否則 \(k\) 就可以放在 \(t\) 而不改變了 \(x\) 數組了。
於是設 \(f_{l,r,k}\) 表示區間 \([l,r]\) 的最大值位置為 \(k\) 時的答案,可以枚舉左區間最大值位置 \(t\) 轉移,時間復雜度 \(O(n^4)\)。
至於判斷是否有區間同時包含 \(t\) 與 \(k\),也可以用一些高超的寫法做到 \(O(n^3)\)。
使用前綴和優化,總時間復雜度 \(O(n^3)\)。
所以你管這叫 B(900) ???
#include<bits/stdc++.h>
using namespace std;
const int N=330,mod=998244353;
int n,m,ans;
int G[N][N],sG[N][N],pre[N][N],f[N][N][N],sf[N][N][N];
int main(){
cin>>n>>m;
for(int i=1;i<=m;i++){
int l,r;
cin>>l>>r;
G[l][r]=1;
}
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
sG[i][j]=sG[i][j-1]+G[i][j];
for(int len=1;len<=n;len++){
for(int l=1;l+len-1<=n;l++){
int r=l+len-1,p=l;
for(int k=l;k<=r;k++){
int tot=(k==r)+(sf[k+1][r][r]+mod-sf[k+1][r][k])%mod;
while(p<=r && sG[p][r]-sG[p][k-1]==0) p++;
if(p<k) f[l][r][k]=(f[l][r][k]+(sf[l][k-1][k-1]+mod-sf[l][k-1][p-1])%mod)%mod;
if(k==l) f[l][r][k]++;
f[l][r][k]=1ll*f[l][r][k]*tot%mod;
sf[l][r][k]=(sf[l][r][k-1]+f[l][r][k])%mod;
}
}
}
cout<<sf[1][n][n];
}
C. 01 Balanced
- 給出 \(M\) 個區間 \(\{[L_i,R_i]\}\),求字典序最小的長度為 \(N\) 的 01 串 \(s\),滿足給出的所有區間內 \(0\) 與 \(1\) 的數量相等。
- \(2 \leq N \leq 10^6\),\(1 \leq M \leq 2 \times 10^5\),\(1 \leq L_i < R_i \leq N\),\(2 \mid R_i-L_i+1\),所有區間互不相同。
因為不會差分約束而沒有切掉
考慮構造一種前綴和 \(S_i=S_{i-1}+(-1)^{s_i}\)。則題目限制等價於 \(S_{L_i-1}=S_{R,i}\)。
另一方面,限制是 \(|S_i-S_{i-1}|=1,i \in [1,N]\)。
考慮差分約束,將第二個限制視為 \(|S_i-S_{i-1}| \leq 1\),從 \(0\) 開始跑最短路。
由於區間長度為偶數且跑的是最短路,不可能出現 \(S_i=S_{i-1}\) 的情況。
由於邊權只有 \(0\) 和 \(1\),可以跑 Dijkstra,甚至 BFS 都行,時間復雜度 \(O(N+M)\)。
#include<bits/stdc++.h>
using namespace std;
const int N=2e6+5,M=2e6+5;
int n,m,s;
struct nod{
int to,nxt,w;
}e[M*2];
int head[N],cnt;
void add(int u,int v,int w){
e[++cnt].to=v;
e[cnt].w=w;
e[cnt].nxt=head[u];
head[u]=cnt;
}
int dis[N];
bool vis[N];
struct abc{
int num,dis;
};
bool operator <(abc x,abc y){
return x.dis>y.dis;
}
priority_queue <abc> q;
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
add(i-1+1,i+1,1);
add(i+1,i-1+1,1);
}
for(int i=1;i<=m;i++){
int u,v;
cin>>u>>v;
u--;
add(u+1,v+1,0);
add(v+1,u+1,0);
}
memset(dis,0x7f,sizeof(dis));
dis[1]=0;
q.push((abc){1,0});
while(!q.empty()){
abc tmp=q.top();
q.pop();
int u=tmp.num;
if(vis[u]) continue;
vis[u]=1;
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].to;
if(!vis[v] && dis[u]+e[i].w<dis[v])
dis[v]=dis[u]+e[i].w,q.push((abc){v,dis[v]});
}
}
for(int i=2;i<=n+1;i++){
if(dis[i]>dis[i-1]) putchar('0');
else putchar('1');
}
}
D. Subset Sum Game
- 黑板上有 \(N\) 個數字 \(A_1,\cdots,A_N\) 和兩個數 \(L,R\)。
- Alice 和 Bob 在玩游戲,Alice 先手。每次操作是擦去黑板上的一個數字。
- \(\frac{N}{2}\) 輪后,若 Alice 擦去的數之和 \(s\) 滿足 \(L \leq s \leq R\),Alice 獲勝;否則 Bob 獲勝。
- 若兩人均采取最優策略,問最后誰會獲勝。
- \(2 \leq N \leq 5000\),\(2 \mid N\),\(1 \leq A_i \leq 10^9\),\(0 \leq L \leq R \leq \sum A_i\)。
還不是很懂結論和證明……
先考慮轉化條件。設 \(S=\sum A_i\),\(sA,sB\) 分別代表兩人所取走的數之和。
則 \(sA-sB=sA-(S-sA)=2sA-S\),\(sA=\dfrac{1}{2}(sA-sB+S)\)。
\(L \leq sA \leq R\) 等價於 \(L \leq \dfrac{1}{2}(sA-sB+S) \leq R\),即 \(2L-S \leq sA-sB \leq 2R-S\)。
再繼續簡化,設 \(X=L+R-S\),則上等價於 \(|(sA-sB)-X| \leq R-L\)。
問題等價於:
有一個變量 \(x\) 初始為 \(L+R-S\),Alice 可以選擇一個 \(A_i\) 給 \(x\) 加上,而 Bob 可以選擇一個 \(A_i\) 給 \(x\) 減掉。Alice 想最大化 \(|X|\) 而 Bob 相反,求 \(x\) 最后的值。
有結論:
對於所有 \(p\),將 \(p,p+X,A_1,\cdots,A_N\) 從小到大排序為 \(a_1,\cdots,a_{N+2}\),則 \(x\) 最后的值即為 \((a_2-a_1)+(a_4-a_3)+\cdots+(a_{N+2}-a_{N+1})\) 的最小值。
暴力枚舉 \(p\) 顯然是不行的,但是若 \(p\) 和 \(p+X\) 均落在兩個區間中間顯然可以左右移動變得更小,所以只需考慮 \(p\) 或 \(p+X\) 為 \(A_t\) 中的某個即可。
時間復雜度 \(O(N^2 \log N)\)。
#include<bits/stdc++.h>
using namespace std;
const long long N=5500,INF=1e18;
long long n,L,R,S,X,anss=INF;
long long a[N];
long long b[N],id;
void solve(long long x){
id=0;
if(x<a[1]) b[++id]=x;
if(x+X<a[1]) b[++id]=x+X;
for(long long i=1;i<=n;i++){
b[++id]=a[i];
if(a[i]<=x && x<a[i+1]) b[++id]=x;
if(a[i]<=x+X && x+X<a[i+1]) b[++id]=x+X;
}
for(int i=1;i<id;i++) if(b[i]>b[i+1]) swap(b[i],b[i+1]);
long long ans=0;
for(long long i=1;i<=id;i+=2) ans+=b[i+1]-b[i];
anss=min(anss,ans);
}
int main(){
cin>>n>>L>>R;
for(long long i=1;i<=n;i++) cin>>a[i],S+=a[i];
sort(a+1,a+n+1);
a[n+1]=INF;
X=S-(L+R);
for(long long i=1;i<=n;i++) solve(a[i]),solve(a[i]-X);
if(anss<=R-L) puts("Alice");
else puts("Bob");
}
E. Cheese
- 有一個長度為 \(N\) 的圓周,設某點 \(O\) 位置為 \(0\),圓周上一點的位置定義為從 \(O\) 沿順時針到該點的距離。有 \(N\) 只老鼠分別站在 \(0.5,1.5,\cdots,N-0.5\) 的位置,有 \(N\) 個放奶酪的位置 \(0,1,\cdots,N-1\),位置 \(i\) 放奶酪的概率為 \(A_i\)。
- 每一次操作,按 \(A_i\) 概率隨機在某個位置放上一塊奶酪。這塊奶酪隨后會沿着圓周順時針游走,直到它被吃掉;當它遇到一只未吃過奶酪的老鼠時,有一半的概率被吃掉。
- 對每只老鼠求出 \(N-1\) 次操作后,它還未吃到奶酪的概率,對 \(998244353\) 取模。
- \(1 \leq N \leq 40\)。
賽后直接切了,你管這叫 E(1600)?
發現放奶酪的順序似乎無關緊要。如果有一前一后兩個奶酪,我們可以不管順序,讓后面的奶酪先走到前面的奶酪處,再兩塊奶酪一起走。這樣顯然不影響結果(因為奶酪和老鼠間不區分)。
考慮計算最后老鼠 \(X\) 還未吃到奶酪的概率。
參考上面的思路,我們可以先把所有奶酪放好(最后要乘上可重排),再讓所有奶酪轉到 \(X\) 前面(這個過程中不會有奶酪經過 \(X\)),這時候只要知道還剩下多少奶酪(或老鼠)即可快速算出答案。
先考慮第一步。設 \(f_{i,j,k}\) 表示轉移到 \(i+X\) 位置,已經放了 \(j\) 塊奶酪,老鼠們已經吃掉放上去的 \(k\) 塊奶酪的概率,最后 \(f_{N,N-1,k}\) 即是需要的東西。
轉移需要分兩步(放奶酪,奶酪走一步讓老鼠吃)。
放奶酪(注意可重排):
吃奶酪:
單次時間復雜度 \(O(N^4)\)。
再考慮第二步。假設現在還剩下 \(k-1\) 塊奶酪(都在 \(X\) 前面)和 \(k\) 只老鼠,我們要求最后 \(X\) 吃不到奶酪的概率。
打表發現答案是 \(\dfrac{1}{2^{k}-1}\),為什么呢?
將老鼠按順時針編號,\(X\) 編號為 \(0\)。設 \(p_i\) 表示編號為 \(i\) 的老鼠最后吃不到奶酪的概率。
只考慮老鼠 \(i\) 與老鼠 \(i+1\)(\(i \in [0,k)\)),假設現在輪到 \(i\),還剩下 \(x\) 塊奶酪,有 \(4\) 種情況:
- \(i\) 和 \(i+1\) 都沒吃,區分不出來,不考慮(留到下一輪考慮)。
- \(i\) 和 \(i+1\) 都吃了,區分不出來,不考慮。
- \(i\) 吃了但 \(i+1\) 沒吃,概率為 \((1-\dfrac{1}{2^x})\dfrac{1}{2^{x-1}}\)。
- \(i\) 沒吃但 \(i+1\) 吃了,概率為 \((1-\dfrac{1}{2^{x-1}})\dfrac{1}{2^x}\)。
所以有 \(p_{i+1}:p_i=(1-\dfrac{1}{2^x})\dfrac{1}{2^{x-1}}:(1-\dfrac{1}{2^{x-1}})\dfrac{1}{2^x}=2:1\),即 \(p_{i+1}=2p_i\)。
自然可得 \(p_i=2^i p_i\)(\(i \in [0,k)\))。
又有 \(\sum p_i=1\),於是 \((2^k-1)p_0=1\),得 \(p_0=\dfrac{1}{2^k-1}\)。得證。
總時間復雜度 \(O(n^5)\),超好寫。
#include<bits/stdc++.h>
using namespace std;
const long long N=44,mod=998244353,inv2=(mod+1)/2;
long long mul[N],inv[N],pw[N],ipw[N];
long long ksm(long long a,long long x){
long long tot=1;
while(x){
if(x & 1ll) tot=1ll*tot*a%mod;
a=1ll*a*a%mod;
x>>=1ll;
}
return tot;
}
long long n,A[N],ans;
long long f[2][N][N],id;
int main(){
cin>>n;
for(long long i=0;i<n;i++) cin>>A[i],A[i]=1ll*A[i]*ksm(100,mod-2)%mod;
mul[0]=inv[0]=1;
for(long long i=1;i<=n;i++) mul[i]=mul[i-1]*i%mod;
inv[n]=ksm(mul[n],mod-2);
for(long long i=n-1;i>=1;i--) inv[i]=inv[i+1]*(i+1)%mod;
pw[0]=ipw[0]=1;
for(long long i=1;i<=n;i++) pw[i]=pw[i-1]*2%mod,ipw[i]=ipw[i-1]*inv2%mod;
for(long long X=0;X<n;X++){
memset(f,0,sizeof(f));
id=0;
f[0][0][0]=1;
for(long long i=1;i<=n;i++){
id^=1;
memset(f[id],0,sizeof(f[id]));
for(long long j=0;j<=n;j++){
for(long long k=0;k<=n;k++){
for(long long p=0;j+p<=n;p++)
f[id][j+p][k]=(f[id][j+p][k]+inv[p]*ksm(A[(X+i)%n],p)%mod*f[id^1][j][k]%mod)%mod;
}
}
if(i==n) break;
id^=1;
memset(f[id],0,sizeof(f[id]));
for(long long j=0;j<=n;j++){
for(long long k=0;k<=j;k++){
f[id][j][k]=(f[id][j][k]+ipw[j-k]*f[id^1][j][k]%mod)%mod;
f[id][j][k+1]=(f[id][j][k+1]+(1+mod-ipw[j-k])*f[id^1][j][k]%mod)%mod;
}
}
}
ans=0;
for(long long i=0;i<=n;i++){
ans=(ans+mul[n-1]*f[id][n-1][i]%mod*ksm(pw[n-i]-1,mod-2)%mod)%mod;
}
cout<<ans<<" ";
}
}
F. Degree Sequence in DFS Order
- 求所有長度為 \(N\) 的序列 \(a_1,\cdots,a_N\),滿足:
- 存在一張 \(N\) 個點 \(M\) 條邊無自環(可重邊)的無標號無向圖,設其 DFS 序(點序列)之一為 \(d_1,\cdots,d_n\),滿足 \(a_i\) 為 \(d_i\) 的度數。
- 答案對 \(998244353\) 取模。
- \(2 \leq N \leq M \leq 10^6\)。
這比上場 F 陽間多了
(寫完后)陽間個鬼,這官方題解真不是一般的簡略,證明根本看不懂啊啊啊啊
Part 1
不妨按 DFS 序標號,即存在 DFS 序之一為 \(1,2,\cdots,N\)。(\(*\))
顯然必要條件是:對於所有 \(u \in [2,N]\),存在 \(v<u\) 使 \((u,v)\) 間連邊。即若現在已走過 \(1 \sim u\),可以走到 \(u+1\)。(\(**\))
但這並不是充分條件,因為 DFS 序會走到底,可能無法選擇 \(u+1\)。
注意到若有 \(a<b<c<d\) 滿足 \((a,c)\) 和 \((b,d)\) 連邊,可以改為 \((a,d)\) 和 \((b,c)\) 連邊,這樣度數與性質均不變。
令邊 \((u,v)\) 的邊權為 \((v-u)^2\),則每次操作必然增大邊權和,故存在邊權和最大的終態無法繼續操作。
假設已走過 \(1 \sim u\),\(u\) 節點不與 \(u+1\) 相連。設 \(u+1\) 與 \(v\) 相連,此時 \(1 < v < u < u+1\) 而 \((1,u)\) 與 \((v,u+1)\) 間連邊,矛盾。因此這個終態是滿足(\(*\))的。
這樣,每一個滿足(\(**\))的圖都可生成一個滿足(\(*\))的圖。我們只需要數滿足(\(**\))的圖的度數序列數量即可。
Part 2
我們來考慮 \(a\) 的限制。
首先顯然有 \(\sum\limits_{i=1}^N a_i=2M\)。
更細節的,由於每個節點都向前面連邊,可以整體考慮前 \(u\) 個點:
- \(\sum\limits_{i \leq u} a_i \geq 2(u-1)+1\)(\(+1\) 是因為前 \(u\) 個點中至少一個要向 \(u+1\) 連邊)。(條件 \(1\))
- 同時還有下限 \(a_{u+1} \leq M-(u-1)\)。(條件 \(2\))
這是必要條件,令人驚訝的是同時也是充分條件。證明如下:
考慮一輪貪心:對於每個點 \(2,3,\cdots,N\),從前面的點選出一個剩余度數最大的點連邊。(由於條件 \(1\),可以做到)
如果一輪后所有點剩余度數均不超過 \(M-(N-1)\),就可以貪心匹配。
假設有 \(a_i'>M-(N-1)\),那么由於 \(\sum a_t'=2M-2(N-1)\),不存在另外的 \(a_j' \geq M-(N-1)\)。由條件 \(2\),\(a_i \leq M-(i-2)\)。下面說明在貪心過程中,\(i\) 號點連接了 \(N-i+1\) 條邊(也是至多),則有 \(a_i' \leq M-(i-2)-(N-i+1)=M-(N-1)\),矛盾。
首先,在貪心到 \(i\) 時,\(i\) 一定會向前面連一條邊。然后,在貪心到 \(k>i\) 時,若存在剩余度數 \(a_{(now)j}>a_{(now)i}\),由於 \(a_i'\) 頂多減到 \(M-(N-1)-1\),\(a_j' \geq M-(N-1)\),這與假設矛盾。因此每一次都可以選擇 \(a_i\),\(a_i\) 連的總度數即為 \(N-i+1\)。證畢。
Part 3
現在真的要開始計數了!
先做些變換。令 \(b_0=a_1\),\(b_i=a_{i+1}-1,i \in [1,N)\)(注意所有 \(b_i\) 均為非負整數),則三個條件變為:
-
\[\sum\limits_{i=0}^{n-1} b_i=2M-(N-1) \]
-
\[\sum\limits_{i < u} b_i \geq u \]
-
\[b_u \leq M-u \]
這是一個類似卡特蘭數的東西,考慮對應到圖上。
如果不考慮第三個條件,相當於從原點出發,每次先向上走 \(b_0\),再右移一格,再向上走 \(b_1\),再右移一格……向上走 \(b_{N-1}\)。最后走到 \((N-1,2M-(N-1))\)。限制是不能越過 \(y=x\) 這條線。
用卡特蘭數的算法可以輕松算出是 \(\dbinom{2M}{N-1}-\dbinom{2M}{N-2}\)。
考慮減去不滿足第三個條件的情況。這里又有一個性質:至多只存在一個 \(K\) 使 \(b_K > M-K\)。證明如下:
設 \(p<q\) 使 \(b_p > M-p\),\(b_q > M-q\)。由條件 \(2\),\(\sum\limits_{i<p} b_i \geq p\),所以 \(\sum\limits_{i=0}^{N-1} b_i \geq \sum\limits_{i<p} b_i+b_p+b_q \geq p+(M-p+1)+(M-q+1)=2M-(q-2) > 2M-(N-1)\),矛盾。
所以,加上第三個條件。我們欽定了 \(b_K \geq M-K+1\),為了維護 \(b_i\) 取非負整數,令 \(b_K \leftarrow b_K-(M-K+1)\),則 \(\sum\limits_{i=0}^{N-1} b_i=2M-(N-1)-(M-K+1)=M-N+K\)。現在的圖看起來是這樣的:
(圖來自官方題解)
不妨將圖分為三角形與矩形上下兩部分來考慮。具體而言,考慮枚舉 \(x\),而第一次躍過 \(K\) 的點 \((x,y)\)(即 \(y \geq K\)),分成前后兩部分計數。方案數實際等於 \((0,0) \rightarrow (x,K-1)\) 乘上 \((x,K) \rightarrow (N-1,M-N+K)\)(想一想,為什么?)。
於是答案為(\(K=0\) 時與 \(K=1\) 答案相同,但是要特判):
交換和號~
眾所周知 \(\sum\limits_{i=0}^n \dbinom{i}{m}=\dbinom{n+1}{m+1}\),所以拆開得到:
預處理組合數,時間復雜度 \(O(N+M)\)。
這短短的三行代碼后是多少艱辛的嘗試與推導啊……
#include<bits/stdc++.h>
using namespace std;
const long long N=2e6+5,mod=998244353;
long long mul[N],inv[N];
long long ksm(long long a,long long x){
long long tot=1;
while(x){
if(x & 1ll) tot=1ll*tot*a%mod;
a=1ll*a*a%mod;
x>>=1ll;
}
return tot;
}
void init(long long lim){
mul[0]=inv[0]=1;
for(long long i=1;i<=lim;i++) mul[i]=mul[i-1]*i%mod;
inv[lim]=ksm(mul[lim],mod-2);
for(long long i=lim-1;i>=1;i--) inv[i]=inv[i+1]*(i+1)%mod;
}
long long C(long long m,long long n){
if(m<n || m<0 || n<0) return 0;
return mul[m]*inv[n]%mod*inv[m-n]%mod;
}
long long n,m,ans;
int main(){
init(N-5);
cin>>n>>m;
for(long long x=0;x<n;x++)
ans=(ans+mod-(C(x+n-1,x+1)+mod-C(2*x-1,x+1)+mod-C(x+n-1,x)+C(2*x-1,x)+mod+(!x))%mod*C(m-x-1,m-n)%mod)%mod;
cout<<(ans+C(2*m,n-1)+mod-C(2*m,n-2)+mod-C(m-1,m-n))%mod;
}