CF1699C The Third Problem
题目:Problem - C - Codeforces
大意就是给你一个长为n的数组,内容是0到n-1,然后给你mex定义,说如果两组数中任意区间这俩的mex都相等,就说这两组数是相似的,然后给你一个数组,问你这个数组的相似数组有多少,包含他自己本身。
8 1 3 7 2 5 0 6 4 1 2 3 4 5 6 7 8
mex定义就是在区间内没有出现的最小值。
一开始区间1 ~ 6(位序),2的可能位置是数6-2=4,3的可能位置数是6-3=3,4在区间外面,所以4的可能位置数是1,然后这时候扩大区间,把4扩进来,因为4已经确定位置了(可以这么想,枚举到4的时候,4前面的都在区间内被确定了,所以4就是外面最小的,它一动mex肯定变,所以它不能动,也就是位置固定),区间扩大为1~8,5的可能位置是8-5=3,6的可能位置2,7的可能位置8-7=1,332*4=72。
其实就是,找两个最小的进行区间维护,按顺序依次看其余数的位置在不在此区间内,不在的话说明要扩大区间,因为要维护任意区间的最小值,动他的话外面区间最小值变了,所以要扩大区间来放那些比他大的数。
1 #include<iostream> 2 #include<cstring> 3 #include<map> 4 using namespace std; 5 const int N=1e5+10; 6 const int mod=1e9 + 7; 7 int a[N]; 8 map<int, int> mp; 9 int main() 10 { 11 int t; 12 scanf("%d",&t); 13 while(t--) 14 { 15 int n; 16 scanf("%d",&n); 17 int l=0,r=0; 18 for(int i=1;i<=n;i++) 19 { 20 scanf("%d",&a[i]); 21 mp[a[i]] = i; 22 if(a[i]==0) l=i; 23 if(a[i]==1) r=i; 24 } 25 if(l>r) swap(l,r); 26 long long res=1; 27 for(int i=2;i<n;i++) 28 { 29 if(mp[i]>r) r=mp[i]; 30 else if(mp[i]<l) l=mp[i]; 31 else res*=r-l-i+1; 32 res%=mod; 33 } 34 cout<<res<<endl; 35 mp.clear(); 36 // memset(a,0,sizeof a); 37 } 38 return 0; 39 }