题目链接:https://vjudge.net/contest/398708#problem/I
DreamGrid has an interesting permutation of 1,2,…,n denoted by a1,a2,…,an. He generates three sequences f, g and h, all of length n, according to the permutation a in the way described below:
For each 1≤i≤n, fi=max{a1,a2,…,ai};
For each 1≤i≤n, gi=min{a1,a2,…,ai};
For each 1≤i≤n, hi=fi?gi.
BaoBao has just found the sequence h DreamGrid generates and decides to restore the original permutation. Given the sequence h, please help BaoBao calculate the number of different permutations that can generate the sequence h. As the answer may be quite large, print the answer modulo 10^9+7.
Input
The input contains multiple cases. The first line of the input contains a single integer T (1≤T≤20000), the number of cases.
For each case, the first line of the input contains a single integer n (1≤n≤105), the length of the permutation as well as the sequences. The second line contains n integers h1,h2,…,hn (1≤i≤n,0≤hi≤10^9).
It’s guaranteed that the sum of n over all cases does not exceed 2?106.
Output
For each case, print a single line containing a single integer, the number of different permutations that can generate the given sequence h. Don’t forget to print the answer modulo 10^9+7.
Input
3
3
0 2 2
3
0 1 2
3
0 2 3
Output
2
4
0
Note
For the first sample case, permutations {1,3,2} and {3,1,2} can both generate the given sequence.
For the second sample case, permutations {1,2,3}, {2,1,3}, {2,3,1} and {3,2,1} can generate the given sequence.
翻译:
原排列p为a1,a2,…,an
fi=max(a1,a2,…,ai),gi=min(a1,a2,…,ai)fi= max (a1,a2,…,ai),gi=min(a1,a2,…,ai )fi=max(a1,a2,…,ai),gi=min(a1,a2,…,ai) ,hi=fi?gihi=fi?gihi=fi?gi,现给出序列h,求满足h的P的个数
分析:
h数列只能是递增的,且第一个数必为0,最大值为n-1
对于一个递增的数列只有两种情况:
1.h[i]=h[i-1]
2.h[i]>h[i-1]
对应第二种情况是:最大值有更新或最小值有更新,对应的结果*2
对应第一种情况:a[i]的取值范围为:
min(a1,a2,,,,,,ai?1)<=a[i]<=max(a1,a2,,,,,,ai?1)min(a_1,a_2,,,,,,a_{i-1})<=a[i]<=max(a_1,a_2,,,,,,a_{i-1})min(a1?,a2?,,,,,,ai?1?)<=a[i]<=max(a1?,a2?,,,,,,ai?1?)
定义大于等于min,小于等于max的数为中间数
假设中间数的个数为num,对应的结果*num
当h[i]>h[i-1]时,h[i]-h[i-1]-1为加上h[i]后新增的中间数的个数
完整代码:
#include<cstdio>
#include<cstring>
#include<math.h>
#include<stdlib.h>
#include<algorithm>
using namespace std;
typedef long long LL;
const int N=1e5+10;
const int mod=1e9+7;
int n;
LL height[N];
int main()
{
int t;scanf("%d",&t);while(t--){
scanf("%d",&n);for(int i=0; i<n; i++)scanf("%lld",&height[i]);bool book=false;for(int i=1; i<n; i++){
if(height[i-1]>height[i]||height[i]>=n){
book=true;break;}}if(height[0]!=0)book=true;if(book)printf("0\n");else{
LL sum=1,ans=0;for(int i=1; i<n; i++){
if(height[i]>height[i-1]){
sum=(sum*2)%mod;ans+=height[i]-height[i-1]-1;///新增的中间数}else{
sum=(sum*ans)%mod;ans--;///用掉一个}}printf("%lld\n",sum%mod);}}return 0;
}