zoukankan      html  css  js  c++  java
  • [51nod] 1250 排列与交换

    第一问,考虑添加第i个数能造成的影响,f[i][j]=f[i-1][j-i+1]+f[i-1][j-i+2]+...+f[i-1][j]

    第二问,对于val[p]=v的地方,从v向p连一条有向边,形成一个由几个环组成的有向图(类似置换?)

    每次交换最多减少一个环,所以最多减少Max(0,n-m)个环,而n个数排成m个环(圆排列)就是第二类斯特林数s[n][m]

    • s[n][m]=s[n-1][m-1]+(n-1)*s[n-1][m] 
    • 理解:当前的数可以新成一个环,也可以插入到之前的环中的n-1个位置
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    
    using namespace std;
    
    inline int rd(){
        int ret=0,f=1;char c;
        while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
        while(isdigit(c))ret=ret*10+c-'0',c=getchar();
        return ret*f;
    }
    
    const int MOD = 1000000007;
    const int MAXN = 4096;
    typedef long long ll;
    
    int n,m,num;
    ll s[2][MAXN];
    ll f[2][MAXN];
    
    int main(){
        n=rd();m=rd();
        f[0][0]=1ll;
        for(int i=1;i<=n;i++){
            for(int j=0;j<=m;j++){
                f[i&1][j]=f[(i+1)&1][j];
                if(j-i>=0)f[i&1][j]-=f[(i+1)&1][j-i];
                while(f[i&1][j]<0) f[i&1][j]+=MOD;
                f[i&1][j]%=MOD;
            }
            for(int j=1;j<=m;j++) f[i&1][j]=(f[i&1][j]+f[i&1][j-1])%MOD;
        }
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                if(j==i){s[i&1][j]=1;continue;}
                s[i&1][j]=s[(i+1)&1][j-1]+(1ll*i-1ll)*s[(i+1)&1][j];
                s[i&1][j]%=MOD;
            }
    
        }
        ll ans=0ll;
        for(int i=m;i>=0;i-=2){
            ans+=f[n&1][i];ans%=MOD;
        }
        cout<<ans<<" ";
        ans=0ll;
        for(int i=n;i>=n-m;i--){
            ans+=s[n&1][i];
            ans%=MOD;
        }
        cout<<ans;
        return 0;
    }
    未经许可,禁止搬运。
  • 相关阅读:
    Bellman算法
    Codeforces Round #378 (Div. 2) D
    运算符优先级
    Kruskal算法
    Java 大数运算
    无根树转有根树
    欧拉函数模板
    HDU 4135 Co-prime(容斥原理)
    快速求n的质因子(数论)
    Markdown中插入数学公式
  • 原文地址:https://www.cnblogs.com/ghostcai/p/9606775.html
Copyright © 2011-2022 走看看