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  } 

 

posted @ 2022-07-15 16:43  Armored_bear  阅读(53)  评论(0)    收藏  举报