今天忽然考數論(霧,有點懵。。ide
出題人頗有意思idea
連接spa
看題的名字——\(excatalan \to\)擴展\(Catalan\)/類\(Catalan\)?code
因而向\(Catalan\)數列上想get
發現對於\(m=0\)時,\(Ans=excatalan(n,0)?\)class
對於其餘狀況,\(Ans=excatalan(n,m)-excatalan(n,m-1)?\)擴展
別問我,我不知道。。。。。。im
我,我不知道。。。。。。img
不知道。。。。。。di
。。。。。。
附上考場代碼。
測完發現 報負了。。。
因而進行改正
//報負 ll f[maxn<<1],inv[maxn<<1]; inline ll power(int a,int b){ ll ans=1; for(;b;b>>=1){ if(b&1) ans=(ll)ans*a%mod; a=(ll)a*a%mod; } return ans; } inline ll Cal(int x,int y){ if(x<y) return 0; if(x<0||y<0) return 0; return (ll)f[x]*inv[y]%mod*inv[x-y]%mod; } inline ll C(int x,int y){ return (ll)(Cal(x*2,x)-Cal(x*2,x-y-1))%mod; } int main(){ // freopen(File".in","r",stdin); // freopen(File".out","w",stdout); int n=read(),m=read(); f[0]=1; for(int i=1;i<=n*2;i++) f[i]=f[i-1]*i%mod; inv[n*2]=power(f[n*2],mod-2); for(int i=n*2;i;i--) inv[i-1]=inv[i]*i%mod; if(m==0) printf("%lld",C(n,0)); else printf("%lld",(C(n,m)-C(n,m-1)+mod)%mod); return 0; }
ll f[maxn<<1],inv[maxn<<1]; inline ll power(int a,int b){ ll ans=1; for(;b;b>>=1){ if(b&1) ans=(ll)ans*a%mod; a=(ll)a*a%mod; } return ans; } inline ll Cal(int x,int y){ if(x<y) return 0; if(x<0||y<0) return 0; return (ll)f[x]*inv[y]%mod*inv[x-y]%mod; } inline ll C(int x,int y){ return (ll)(Cal(x*2,x)-Cal(x*2,x-y-1)+mod)%mod; } int main(){ // freopen(File".in","r",stdin); // freopen(File".out","w",stdout); int n=read(),m=read(); f[0]=1; for(int i=1;i<=n*2;i++) f[i]=f[i-1]*i%mod; inv[n*2]=power(f[n*2],mod-2); for(int i=n*2;i;i--) inv[i-1]=inv[i]*i%mod; if(m==0) printf("%lld",C(n,0)); else printf("%lld",(C(n,m)-C(n,m-1)+mod)%mod); return 0; }
思考題答案:蘑菇的擬態平常
這道題讓求了個 指望混亂度,cb不會指望\(QAQ\)。
因而我打了個隨機化,輸出了樣例。。。
設 \(f[i]\)表明以 \(a[i]\)爲終點,上一個數大於 \(a[i]\)的方案數。\(g[i]\)表明上個數 小於 \(a[i]\)的方案數。轉移時先按 \(a[i]\)從小到大枚舉 \(i\),再按 \(a[j]\)從大到小枚舉 \(j\), 若\(j \lt i\) ,用\(f[j]\)更新\(g[i]\),不然用\(g[i]\)更新\(f[j]\)。
時間複雜度\(O(n^2)\),空間爲\(O(n)\)。
而後,就沒了
int n,mod,ans; int f[maxn],g[maxn]; int a[maxn],b[maxn]; inline void change(int &x,int y){ x+=y; if(x>=mod) x-=mod; } int main(){ // freopen(File".in","r",stdin); // freopen(File".out","w",stdout); n=read(); mod=read(); for(int i=1;i<=n;i++){ a[i]=read(); b[a[i]]=i; } //mem(f,1); mem(g,0);//不知道爲何,我宏定義的memset掛了。。。 for(int i=1;i<=n;i++) f[i]=1,g[i]=0; for(int i=1;i<=n;i++) for(int j=i-1;j;j--) if(b[j]<b[i]) change(f[i],g[j]); else change(g[j],f[i]); for(int i=1;i<=n;i++) change(ans,f[i]); //mem(f,0); mem(g,1); for(int i=1;i<=n;i++) f[i]=0,g[i]=1; for(int i=1;i<=n;i++) for(int j=i-1;j;j--) if(b[j]<b[i]) change(f[i],g[j]); else change(g[j],f[i]); for(int i=1;i<=n;i++) change(ans,g[i]); change(ans,mod-n%mod); printf("%d",ans); return 0; }
\[ The \quad End \]
\[ \text{人生只不過,一場廝殺。赤血染黃沙,青春成白髮。如果真英雄,怎會怕。-《真英雄》張衛健} \]