文章目录
- [I. Interesting Permutation](https://codeforces.com/gym/102394/problem/I)
-
- 题意
- 解题思路
- 代码
I. Interesting Permutation
题意
给你一个数字n,然后有一个长度为n的数列,这个数列的第 i 项值时某个数列的前 i 项的最大值减去最小值的到的结果,问你用着n个数字能构造出来多少种长度为n的数列。
解题思路
不成立的情况就不总结了。直接说怎么构造可行解吧。
如果某一项和前一项不相等,那么我们就可以在数量上乘以2,然后记录差值-1,如果相等的话就用前面累计的差值乘以ans,差值和减一,为什么这样可以呢?因为如果这个值和前面的不等说明,该位置的数值可以是前 i 个数的最大值,也可以是最小值,如果相等,那么我们已经让第一次出现的是最值了我们要插入的数,肯定是不能对该结果没影响的,所以就是之前差值和中的任意一个就可以。
代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int mx=2000200;
const ll mod=1000000007;
ll a[mx];int main(){
ios::sync_with_stdio(0);int t,n;cin>>t; while(t--){
ll ans=1;cin>>n;bool f=0;for(int i=1;i<=n;i++){
cin>>a[i];if(a[i]<a[i-1]||a[i]>=n){
f=1;}}if(f||a[1]!=0){
cout<<"0\n";continue;}ll cnt=0;for(int i=2;i<=n;i++){
if(a[i]>a[i-1]){
ans=ans*2%mod;cnt+=a[i]-a[i-1]-1;}else{
ans=ans*cnt%mod;cnt--;}}cout<<ans<<"\n";}return 0;
}