HDU6044 & 2017 Multi-University Training Contest - Team 1

Limited Permutation

Problem Description
As to a permutation p1,p2,⋯,pn from 1 to n, it is uncomplicated for each 1≤i≤n to calculate (li,ri) meeting the condition that min(pL,pL+1,⋯,pR)=pi if and only if li≤L≤i≤R≤ri for each 1≤L≤R≤n.

Given the positive integers n, (li,ri) (1≤i≤n), you are asked to calculate the number of possible permutations p1,p2,⋯,pn from 1 to n, meeting the above condition.

The answer may be very large, so you only need to give the value of answer modulo 109+7.

Input
The input contains multiple test cases.

For each test case:

The first line contains one positive integer n, satisfying 1≤n≤106.

The second line contains n positive integers l1,l2,⋯,ln, satisfying 1≤li≤i for each 1≤i≤n.

The third line contains n positive integers r1,r2,⋯,rn, satisfying i≤ri≤n for each 1≤i≤n.

It’s guaranteed that the sum of n in all test cases is not larger than 3⋅106.

Warm Tips for C/C++: input data is so large (about 38 MiB) that we recommend to use fread() for buffering friendly.
size_t fread(void *buffer, size_t size, size_t count, FILE *stream); // reads an array of count elements, each one with a size of size bytes, from the stream and stores them in the block of memory specified by buffer; the total number of elements successfully read is returned.

Output
For each test case, output “Case #x: y” in one line (without quotes), where x indicates the case number starting from 1 and y denotes the answer of corresponding case.

Sample Input
3
1 1 3
1 3 3
5
1 2 2 4 5
5 2 5 5 5

Sample Output
Case #1: 2
Case #2: 3

#include<bits/stdc++.h>
using namespace std;
using LL=int64_t;
const int INF=0x3f3f3f3f;
const int mod=1e9+7;
const int maxn=1e6+5;
LL fac[maxn];
int tnum;

struct Node {
    int l,r;
    int cnt;
    bool operator < (const Node & b) const {
        if(l==b.l) return r>b.r;
        else return l<b.l;
    }
}node[maxn];


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;

void init() {
    fac[0]=1;
    for(int i=1;i<maxn;i++)
        fac[i]=fac[i-1]*i%mod;
}

LL q_pow(LL x,LL n) {
    LL ans=1;
    while(n){
        if(n&1) ans=ans*x%mod;
        n>>=1;
        x=x*x%mod;
    }
    return ans;
}

LL C(LL n,LL m) {
    if(m>n) return 0;
    return fac[n]*q_pow(fac[m]*fac[n-m]%mod,mod-2)%mod;
}

LL dfs(int x,int y) {
    int num=tnum;
    if(x>y) return 1;
    tnum++;
    if(node[num].l==x&&node[num].r==y)
        return dfs(x,node[num].cnt-1)*dfs(node[num].cnt+1,y)%mod*C(y-x,node[num].cnt-x)%mod;
    return 0;
}

int main()
{
    init();
    int kase=1,n;
    while(read(n), !fastIO::IOerror) {
        tnum=1;
        for(int i=1;i<=n;i++) read(node[i].l);
        for(int i=1;i<=n;i++) read(node[i].r);
        for(int i=1;i<=n;i++) node[i].cnt=i;
        sort(node+1,node+n+1);
        printf("Case #%d: %lld\n",kase++,dfs(1,n));
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值