1015 模拟赛

写在前面

今天忽然考数论(雾,有点懵。。ide

出题人颇有意思ts.pngidea

T1煎蛋的疑惑(excatalan)

连接spa

Idea

看题的名字——\(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

。。。。。。

附上考场代码。

测完发现 报负了。。。ts.png

因而进行改正

Code

//报负
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;
}

T2蘑菇(shimeji)

连接

Idea

思考题答案:蘑菇的拟态平常清闲.gif

这道题让求了个 指望混乱度,cb不会指望\(QAQ\)

因而我打了个随机化,输出了样例。。。youl.pngyoul.png

Code

 

T3墙(wall)

连接

Idea

\(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)\)

而后,就没了看戏.jpg

Code

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{人生只不过,一场厮杀。赤血染黄沙,青春成白发。如果真英雄,怎会怕。-《真英雄》张卫健} \]

相关文章
相关标签/搜索