You are given a permutation a1,a2,…,an of integers from 0 to n−1. Your task is to find how many permutations b1,b2,…,bn are similar to permutation a.
Two permutations a and b of size n are considered similar if for all intervals [l,r] (1≤l≤r≤n), the following condition is satisfied:
MEX([al,al+1,…,ar])=MEX([bl,bl+1,…,br]),where the MEX of a collection of integers c1,c2,…,ck is defined as the smallest non-negative integer x which does not occur in collection c. For example, MEX([1,2,3,4,5])=0, and MEX([0,1,2,4,5])=3.
Since the total number of such permutations can be very large, you will have to print its remainder modulo 10^9+7.
In this problem, a permutation of size nn is an array consisting of nn distinct integers from 0 to n−1 in arbitrary order. For example, [1,0,2,4,3] is a permutation, while [0,1,1] is not, since 1 appears twice in the array. [0,1,3] is also not a permutation, since n=3 and there is a 3 in the array.
Input
Each test contains multiple test cases. The first line of input contains one integer tt (1≤t≤10^4) — the number of test cases. The following lines contain the descriptions of the test cases.
The first line of each test case contains a single integer nn (1≤n≤10^5) — the size of permutation a.
The second line of each test case contains nn distinct integers a1,a2,…,an (0≤ai<n) — the elements of permutation a.
It is guaranteed that the sum of n across all test cases does not exceed 10^5.
Output
For each test case, print a single integer, the number of permutations similar to permutation aa, taken modulo 10^9+7.
Example
input
5 5 4 0 3 2 1 1 0 4 0 1 2 3 6 1 2 4 0 5 3 8 1 3 7 2 5 0 6 4
output
2 1 1 4 72
Note
For the first test case, the only permutations similar to a=[4,0,3,2,1] are [4,0,3,2,1] and [4,0,2,3,1].
For the second and third test cases, the given permutations are only similar to themselves.
For the fourth test case, there are 4 permutations similar to a=[1,2,4,0,5,3]:
- [1,2,4,0,5,3]
- [1,2,5,0,4,3]
- [1,4,2,0,5,3]
- [1,5,2,0,4,3]
题意: 给出一个长度为n的排列,询问有多少个排列和它相似,两排列相似定义为对于任意一个区间,两者的MEX均相等,MEX是区间内未出现的最小非负整数。
分析: 首先考虑一下0的位置是否可以改变,如果改变了,那0那个位置的区间MEX就会改变,所以0的位置是不能动的,再考虑1的位置是否可以改变,这时可以看一下0的位置和1的位置构成的区间,设为[l,r],假如1改变了位置,那这个区间的MEX值一定是1,所以1的位置也不能变。接下来考虑2的位置,如果2在[l,r]之间,那2一定不能移动出这个区间,也就是2的位置只能选在这个区间内部,共有(区间长度-2)种选择,但如果2的位置不在[l,r]之间,那2的位置也就不能动了,这点可以分情况讨论得到,同时区间[l,r]也要被更新。对于剩下的数依此类推直到遍历完所有数,每个数的位置选择数相乘就得到了答案。
具体代码如下:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <string>
using namespace std;
int a[100005], pos[100005];
const int mod = 1e9+7;
signed main()
{
int T;
cin >> T;
while(T--){
int n, l, r;
scanf("%d", &n); //n = 1
for(int i = 1; i <= n; i++){
scanf("%d", &a[i]);
if(a[i] == 0) l = i;
if(a[i] == 1) r = i;
pos[a[i]] = i;
}
if(r < l) swap(l, r);
long long res = 1;
for(int i = 2; i < n; i++){
if(pos[i] > l && pos[i] < r)
res = res*(r-l+1-i)%mod;
else{
if(pos[i] < l)
l = pos[i];
if(pos[i] > r)
r = pos[i];
}
}
printf("%lld\n", res);
}
return 0;
}