• HDU 6044


    题意略。

    思路:

    I.对于整个区间a1,....,an,必然有一个区间[1,n]与之对应,因为a1,...,an是1,...,n的一个排列,所以在[1,n]中定然有一个最小的数字1,

    如果最大的区间[l,r]长度比[1,n]小,那么我们可以知道在[l,r]之外的数字是依然大于1的,这使得1这个数字没有合法的地方可放。

    II.起于1左端的区间不可能终于1的右端。

    III.数字1左端的部分类似于整体,因为左端也类似地有一个最小的数字。

    IV.要想知道整体的方案数有多少,假设可以由f(1,n)算出,那么f(1,n) = f(1,mid - 1) * f(mid + 1,r) * C(n - 1,mid - 1)。

    V.这个题递归的顺序可以预先算出来。

    #include<bits/stdc++.h>
    //#pragma comment(linker,"/STACK:1024000000,1024000000")
    using namespace std;
    typedef long long LL;
    const LL mod = 1e9 + 7;
    const LL maxn = 1e6 + 5;
    
    inline bool scan_d(int& ret){
        char c;int sgn;
        if(c = getchar(),c == EOF) return 0;
        while(c != '-' && (c < '0' || c > '9')) c = getchar();
        sgn = (c == '-') ? -1 : 1;
        ret = (c == '-') ? 0 : (c - '0');
        while(c = getchar(),c >= '0' && c <= '9') ret = ret * 10 + (c - '0');
        ret *= sgn;
        return 1;
    } 
    
    struct node{
        int l,r,id;
        node(int a = 0,int b = 0){
            l = a,r = b;
        }
        bool operator<(const node& nd) const{
            if(l != nd.l) return l < nd.l;
            return r > nd.r;
        }
    };
    
    int cnt;
    LL fac[maxn],inv[maxn];
    node store[maxn];
    bool flag;
    
    LL exgcd(LL a,LL b,LL& x,LL& y){
        if(a == 0 && b == 0) return -1;
        if(b == 0){
            x = 1,y = 0;
            return a;
        }
        LL d = exgcd(b,a % b,y,x);
        y -= a / b * x;
        return d;
    }
    LL rev(LL a,LL n){
        LL x,y;
        LL d = exgcd(a,n,x,y);
        if(d == 1) return (x % n + n) % n;
        else return -1;
    }
    void init(){
        fac[0] = 1;
        for(LL i = 1;i < maxn;++i) fac[i] = fac[i - 1] * i % mod;
        
        inv[maxn - 1] = rev(fac[maxn - 1],mod);
        for(LL i = maxn - 2;i >= 0;--i){
            inv[i] = inv[i + 1] * (i + 1) % mod;
            //printf("inv[%d] == %lld
    ",i,inv[i]);
        }
    }
    LL C(int n,int m){
        return ((fac[n] * inv[m]) % mod) * inv[n - m] % mod;
    }
    LL dfs(int l,int r){
        //printf("now l == %d r == %d
    ",l,r);
        if(flag) return 0;
        if(l > r) return 1;
        
        if(store[cnt].l != l || store[cnt].r != r){
            flag = true;
            return 0;
        } 
        node cur = store[cnt++];
        int mid = cur.id;
        LL lft = 1,rht = 1,c = 1;
        lft = dfs(l,mid - 1);
        rht = dfs(mid + 1,r);
        c = C(r - l,mid - l);
        //printf("c == %lld
    ",c);
        //printf("---> %lld
    ",(lft * rht % mod) * c % mod);
        return (lft * rht % mod) * c % mod;
    }
    
    int main(){
        int cas = 1,n;
        init();
        while(scan_d(n)){
            flag = false;
            cnt = 1;
            for(int i = 1;i <= n;++i) scan_d(store[i].l);
            for(int i = 1;i <= n;++i) scan_d(store[i].r),store[i].id = i;
            sort(store + 1,store + n + 1);
            LL ans = dfs(1,n);
            printf("Case #%d: %lld
    ",cas++,ans);
        }
        return 0;
    }

     

  • 相关阅读:
    wordpress程序打开太慢的解决方案(一步搞定)
    Emeditor代码编辑器常见的正则表达式总结
    网站关键词排名突然消失的原因正在努力侦破
    如何禁止百度对网站进行转码
    【web前端开发】浏览器兼容性处理大全
    导航悬浮于顶部代码学习
    用最简单的代码写出banner图轮播效果
    这段时间大量网站被k的原因分析
    Python的lambda学习
    随机数生成验证码
  • 原文地址:https://www.cnblogs.com/tiberius/p/8681207.html
Copyright © 2020-2023  润新知