L - Limited Permutation

 递归爆栈,改成非递归的模板题

    #include <bits/stdc++.h>
    using namespace std;
    typedef int lint;
    typedef long long LL;
    typedef pair<lint,lint> pii;
    const lint maxn = 1000005;
    lint l[maxn],r[maxn];
    const LL mod = 1e9 + 7;
    LL frac[maxn], carf[maxn];
    LL inv(LL x){
        if (x==1) return 1;
        else return (mod-mod/x)*inv(mod%x)%mod;
    }
    void init(){
        frac[0]=1;
        for (int i=1;i<=1000003;i++)
            frac[i]=frac[i-1]*i%mod;
        carf[1000003]=inv(frac[1000003]);
        for (int i=1000003;i>=1;i--)
            carf[i-1]=carf[i]*i%mod;
    }
    LL C(int n, int m){
        if (m>n) return 0;
        else return frac[n]*carf[n-m]%mod*carf[m]%mod;
    }
    map<pii,lint> ma;
    struct type{
        lint l,r,cnt;
        bool f;
        lint flag;
        type( lint ccnt = 0,lint ll=0,lint rr = 0,bool ff = false,lint fff = 0 ){
            l = ll;r=rr;f =ff;
            flag = fff;
            cnt = ccnt;
        }
    };
    type st[maxn];
    lint top;
    LL dfs( lint cnt,lint l,lint r,bool f ){
        /*if( l > r ) return 1LL;
        LL ans = 1;
        if(f)ans = ans * C( cnt,r-l+1 )%mod;
        auto p =  ma.find(pii(l,r));
        lint pos = p->second;
        ma.erase(p);
        ans = ans * dfs( r-l,pos+1,r,true ) % mod;
        ans = ans*dfs( r-l,l,pos-1,false ) %mod;
        return ans;*/
        LL ans = 1;
        st[++top] = type( cnt,l,r,f,0 );
        while(top>0){
            type cur = st[top];
            if(cur.f&&!cur.flag)ans = ans * C( cur.cnt,cur.r-cur.l+1 )%mod;
            auto p =  ma.find(pii(cur.l,cur.r));
            if( p == ma.end() ) return 0;
            lint pos = p->second;
            //ma.erase(p);
            if( !cur.flag ){
                st[top].flag++;
                if( pos + 1<= cur.r ){
                    st[++top] = type( cur.r-cur.l,pos+1,cur.r,true );
                }
            }else if( cur.flag == 1 ){
                st[top].flag++;
                if( cur.l <= pos-1 ){
                    st[++top] = type( cur.r-cur.l,cur.l,pos-1,false );
                }
            }else{
                top--;
            }
        }
        return ans;
    }
    int main(){
        lint n;
        init();
        lint ca  = 0;
        while( 1 == scanf("%d",&n) ){
            printf("Case #%d: ",++ca);
            ma.clear();
            top = 0;
            for( lint i = 1;i <= n;i++ ) scanf("%d",&l[i]);
            for( lint i = 1;i <= n;i++ ) scanf("%d",&r[i]);
            for( lint i = 1;i <= n;i++ ) ma[pii(l[i],r[i])] = i;
            LL ans = dfs( n,1,n,true );
            printf("%I64d\n",ans);
        }
        return 0;
    }

[close]

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值