hdu6044 Limited Permutation【读入优化+dfs】

来源:互联网 发布:360 cn域名多少钱买的 编辑:程序博客网 时间:2024/06/05 22:34

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6044
题意:有长度为n的序列,分别表示l[i]和r[i],然后让你构造一个a序列,a[i]满足在[l[i],r[i]]区间里面,a[i]为最小值,满足这样条件的序列有多少种
解析:首先根据题面的限定,肯定存在一个区间i是[1,n],对于这个区间,可以说第i个值已经确定了,因为这个区间是当前的整个区间,对于剩下的来说,肯定从剩下的n-1个数中选i-1个数出来填在左边,而剩下的填在右边,接下来在乘上左右区间的各自的方法数,总的计数方案应该为ans = dfs(1,i-1)*dfs(i+1,n) *C(r-l,i-l),所以需要递归往下划分,此时再往下划分的话,就会把这个区间分为[1,i-1]和[i+1,n],依次递归向下,就可以吧所有的区间扫一遍

#include <bits/stdc++.h>using namespace std;const int maxn = 3e6+100;const int mod = 1e9+7;typedef long long ll;namespace fastIO{    #define BUF_SIZE 100000    //fread -> read    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 == '\n' || ch == '\r' || ch == '\t';    }    inline void read(int &x)    {        char ch;        while (blank(ch = nc()));        if (IOerror)            return;        for (x = ch - '0'; (ch = nc()) >= '0' && ch <= '9'; x = x * 10 + ch - '0');    }    #undef BUF_SIZE};using namespace fastIO;struct node{    int l,r,id;    bool operator < (const node &b)const    {        if(l==b.l)            return r>b.r;        return l<b.l;    }}a[maxn];ll h[maxn];ll qpow(ll x,ll n){    ll res = 1;    while(n)    {        if(n&1)            res = res*x%mod;        x = x*x%mod;        n >>= 1;    }    return res;}ll C(int n,int m){    ll a = h[n];    ll b = h[m]*h[n-m]%mod;    return a*qpow(b,mod-2)%mod;}int id;ll dfs(int l,int r){    if(a[id].l!=l || a[id].r!=r)        return 0;    int last = a[id].id;    id++;    ll ansl = 1,ansr = 1;    if(l<=last-1)        ansl = dfs(l,last-1);    if(r>=last+1)        ansr = dfs(last+1,r);    return ansl*ansr%mod*C(r-l,last-l)%mod;}int main(void){    h[0] = 1;    for(int i=1; i<maxn; i++)        h[i] = (h[i-1]*i)%mod;    int n;    int case_t = 1;    while(read(n),!fastIO::IOerror)    {        for(int i=1;i<=n;i++)            read(a[i].l);        for(int i=1;i<=n;i++)        {            read(a[i].r);            a[i].id = i;        }        sort(a+1,a+n+1);        id = 1;        ll ans = dfs(1,n);        printf("Case #%d: %I64d\n",case_t++,ans);    }    return 0;}
原创粉丝点击