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;
}