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 .
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.
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
Source
题意:给你n个区间,然后让你确定p数列(p数列为1~n中的数),第i个区间【li,ri】表示的是以p【i】为最小值的的最大区间,由此我们也可以得出p[i]<p[li-1]和p[i]<p[ri+1](如果存在的话),我们根据特定的方式给n个区间排序,L升序r降序的方式排序,如果有结果的这样排完序第一个区间一定是[1,n],我们再根据这个大区间分析如果最后有结果的话肯定存在[1,i-1]和[i+1,r]这两个区间(大区间的是第i个区间),在把这两个小区间看作大区间递归下去,我们会发现这其实类似于我们学的先序遍历,而我们之前排完序的其实与这个先序一一对应的(如果不对应的话就表示最后结果无解)
然后就是结果的求法了
最后结果==左区间值*右区间值*本区间值
左右区间就不用说了,是一个递归过程
当前区间为[li,ri],一共ri-li+1个数,出去我们确定的第i个数还剩ri-li个数,我们要从ri-li个数中选出i-li个数放在第i个数的左边(剩下的当然就是右边了)
本区间值=c(ri-li,i-li);
还要注意这题题卡时间,所以要用到超神读入挂
ac代码:
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
const int Maxn=1e6+5;
long long fac[Maxn],inv[Maxn];
const int mod = 1e9 + 7;
int flag,ph;
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表示i的阶乘%mod的值 inv表示i的阶乘的逆元%mod的值
{
inv[0] = fac[0] = inv[1] = fac[1] = 1;
for(int i = 1; i < Maxn; i++)
fac[i] = fac[i - 1] * i % mod;
for(int i = 2; i < Maxn; i++)
inv[i] = (mod - (mod / i)) * inv[mod % i] % mod;//lucas定理求逆元
for(int i = 1; i < Maxn; i++)
inv[i] = inv[i - 1] * inv[i] % mod;
}
long long get_c(int n,int m)
{
return (fac[n]*inv[m]%mod)*inv[n-m]%mod;
}
struct node
{
int l,r,id;
}a[Maxn];
bool cmp(node a,node b)
{
if(a.l!=b.l)
return a.l<b.l;
else
return a.r>b.r;
}
long long dfs(int l,int r)
{
if(flag==0)
return 0;
if(l>r)
return 1;
if(a[ph].l!=l||a[ph].r!=r)
{
flag=0;
return 0;
}
node now=a[ph++];
long long ans=get_c(now.r-now.l,now.id-now.l)*dfs(now.l,now.id-1)%mod;
ans=ans*dfs(now.id+1,now.r)%mod;
return ans;
}
int main()
{
init();
int n,p=0;
while(read(n),!IOerror)
{
p++;
for(int i=0;i<n;i++)
read(a[i].l),a[i].id=i+1;
for(int i=0;i<n;i++)
read(a[i].r);
sort(a,a+n,cmp);
flag=1;
ph=0;
printf("Case #%d: %lld\n",p,dfs(1,n));
}
return 0;
}