I - Interesting Permutation

DreamGrid has an interesting permutation of 1,2,…,n1,2,…,n denoted by a1,a2,…,ana1,a2,…,an. He generates three sequences ff, gg and hh, all of length nn, according to the permutation aa in the way described below:

  • For each 1≤i≤n1≤i≤n, fi=max{a1,a2,…,ai}fi=max{a1,a2,…,ai};
  • For each 1≤i≤n1≤i≤n, gi=min{a1,a2,…,ai}gi=min{a1,a2,…,ai};
  • For each 1≤i≤n1≤i≤n, hi=fi−gihi=fi−gi.

BaoBao has just found the sequence hh DreamGrid generates and decides to restore the original permutation. Given the sequence hh, please help BaoBao calculate the number of different permutations that can generate the sequence hh. As the answer may be quite large, print the answer modulo 109+7109+7.

Input

The input contains multiple cases. The first line of the input contains a single integer TT (1≤T≤200001≤T≤20000), the number of cases.

For each case, the first line of the input contains a single integer nn (1≤n≤1051≤n≤105), the length of the permutation as well as the sequences. The second line contains nn integers h1,h2,…,hnh1,h2,…,hn (1≤i≤n,0≤hi≤1091≤i≤n,0≤hi≤109).

It's guaranteed that the sum of nn over all cases does not exceed 2⋅1062⋅106.

Output

For each case, print a single line containing a single integer, the number of different permutations that can generate the given sequence hh. Don't forget to print the answer modulo 109+7109+7.

Input

2
welcome
toparticipate
inthe
ccpccontest
inharbin
inoctober
harvest
belong
ninja
reset
amazing
intriguing

Output

No
Yes

题解

Shortest judge solution: 543 Bytes.
首先特判 h 1 = 0 , h i n 以及 h i > h i +1 的情况,这些情况都是无解。
然后依次考虑 h 2 , h 3 , . . . , h n 。如果 h i > h i 1 ,那么 a i 既可以是前 i 个数的最大值,也可以
是前 i 个数的最小值,将答案乘以 2 ,同时新增中间 h i h i 1 1 个空位没填;如果 h i = h i 1
那么需要消耗一个空位,并将答案乘以空位数。
时间复杂度 O ( n )
当时没有A出来,这道题是一道思维题,因为h是这个数列的最大值减去最小值,因此不会有h>=n的情况,根据题意可以知道h一定是单调递增的,那么如果h[i]<h[i-1]那么这个一定不会成立,而且h【1】一定是0不会是其他的结果
然后在考虑h【i】>h【i-1】的情况如果出现这种情况,那么新增加的a【i】这个数一定是比之前数列出现的最大数或者是比之前数列出现的最小数。那么比之前的结果数目就增加2的倍数,也就是a【i】为最大数插入末尾然后前边的数列的全排列加上a【i】为最小数插入末尾然后前边的数列的全排列,即sum=sum+sum=2*sum,然后根据h【i】-h【i-1】可以求出其差值,然后差值减去1就可以知道中间的空位也就是可以有几个数插入进去,然后当h【i】=h【i-1】的时候这个数字不是最大数也不是最小数,然后总结果就是差值sum=sum*空位,然后空位减去一个。至于为啥这样,我描述不出来。。。。
看代码吧!
 
#include <bits/stdc++.h>
using namespace std;
long long a[100000+10];
const long long mod=1000000000+7;
int main()
{
	int t;
	std::ios::sync_with_stdio(false);
	cin>>t;
	while(t--)
	{
		int n;
		cin>>n;
		memset(a,0,sizeof(a));
		long long sum=1,num=0;
		int flag=0;
		for(int i=0;i<n;i++)
		{
			cin>>a[i];
			if(a[i]<a[i-1]||a[i]>=n) flag=1;
		}
		if(a[0]!=0||flag)
		{
			cout<<0<<endl;
		}
		else
		{
			for(int i=1;i<n;i++)
			{
				if(a[i]>a[i-1]&&a[i]<n)
				{
					sum*=2;
					num+=(a[i]-a[i-1]-1);
					sum=sum%mod;
				}
				else if(a[i]==a[i-1]&&a[i]<n)
				{
					sum=sum*num;
					sum=sum%mod;
					num--;
				}
			}
			cout<<sum%mod<<endl;
		}
	}
	return 0;
 } 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值