zoukankan      html  css  js  c++  java
  • HDU 6044 Limited Permutation(搜索+读入优化)

    【题目链接】 http://acm.hdu.edu.cn/showproblem.php?pid=6044

    【题目大意】

      给出两个序列li,ri,现在要求构造排列p,使得对于区间[li,ri]来说,
      pi是区间中最小的值,且[li,ri]是满足pi是区间最小值的最大区间

    【题解】

      我们发现对于区间[L,R],我们可以按照Dfs序找到支配这个区间的pi,
      对于找到的每个pi,我们将剩余的数字划分到左右区间继续进行dfs,
      如果在某个区间我们无法寻求到解,那么整个dfs的过程就被判定为无解,
      除去最小值作为根节点之后,左右子树的节点分配就是一个组合数了。

    【代码】

    #include <cstdio>
    #include <algorithm>
    #include <utility>
    #include <map>
    using namespace std;
    typedef long long LL;
    typedef pair<int,int> P;
    const LL mod=1000000007;
    const int N=1000010;
    namespace fastIO{
        #define BUF_SIZE 100000
        bool IOerror=0;
        inline char nc(){
            static char buf[BUF_SIZE],*p1=buf+BUF_SIZE,*pend=buf+BUF_SIZE;
            if(p1==pend){
                p1=buf;
                pend=buf+fread(buf,1,BUF_SIZE,stdin);
                if(pend==p1){
                    IOerror=1;
                    return -1;
                }
            }return *p1++;
        }
        inline bool blank(char ch){
            return ch==' '||ch=='
    '||ch=='
    '||ch=='	';
        }
        inline bool read(int &x){
            char ch;
            while(blank(ch=nc()));
            if(IOerror)return 0;
            for(x=ch-'0';(ch=nc())>='0'&&ch<='9';x=x*10+ch-'0');
            return 1;
        }
        #undef BUF_SIZE
    };
    namespace Comb{
        int f[N],rf[N];
        LL inv(LL a,LL m){return(a==1?1:inv(m%a,m)*(m-m/a)%m);} 
        LL C(int n,int m){
            if(m<0||m>n)return 0;
            return (LL)f[n]*rf[m]%mod*rf[n-m]%mod;
        }
        void init(){
            f[0]=1;for(int i=1;i<=1000000;i++)f[i]=(LL)f[i-1]*i%mod;
            rf[1000000]=inv(f[1000000],mod);
            for(int i=1000000;i;i--)rf[i-1]=(LL)rf[i]*i%mod;
        }
    }
    int l[N],r[N],n;
    map<P,int> M;
    LL dfs(int l,int r){
        // printf("%d %d
    ",l,r);
        if(l>r)return 1;
        int x=M[P(l,r)]; if(!x)return 0;
        return Comb::C(r-l,r-x)*dfs(l,x-1)%mod*dfs(x+1,r)%mod;
    }
    int main(){
        Comb::init();
        for(int cas=1;fastIO::read(n);cas++){
            M.clear();
            for(int i=1;i<=n;i++)fastIO::read(l[i]);
            for(int i=1;i<=n;i++)fastIO::read(r[i]);
            for(int i=1;i<=n;i++)M[P(l[i],r[i])]=i;
            LL ans=dfs(1,n);
            printf("Case #%d: %lld
    ",cas,ans);
        }return 0;
    }
  • 相关阅读:
    JavaScript的作用域和块级作用域概念理解
    正则表达式中组的理解
    正则表达式的字符组取反(负值字符集合/范围)^必须出现在起始位置
    利用TortoiseGit(小乌龟)将项目上传至GitHub网站
    (.Net) NLog 记录日志功能
    关于网站中引用COM组件的部署问题
    备份与还原ORACLE数据库(通过CMD命令执行)
    C# Task中的Func, Action, Async与Await的使用
    ASP.NET WebAPI 项目示例(增删改查)
    .NET内存泄漏(之 静态事件)
  • 原文地址:https://www.cnblogs.com/forever97/p/hdu6044.html
Copyright © 2011-2022 走看看