题意:若数组中一个数前的所有数都比这个数小,那么定义它为一个record。若去掉某一个元素使剩下的数组中record最多,求这个元素
分析:对每个元素,考虑去掉它的情况。若第i个元素前有i-1个小于它的元素,则去掉该元素后这个数组前i个元素的record总数-1.若第i个元素前有i-2个小于它的元素,那么去掉前i个元素中大于第i个元素的那个元素后,前i个元素的record总数+1.若第i个元素前有两个及以上的元素大于它,那么无论去掉它还是大于它的元素,前i个元素record总数不变。循环完毕后找到去掉它后record总数增加最多的元素即可。
实现:用树状数组实现快速查询小于某元素的元素个数,用STL的set(红黑树)的lower_bound实现快速找到大于某元素的最小元素。
AC代码:
1 #include <iostream> 2 #include<algorithm> 3 #include<set> 4 #define MAXN 100005 5 using namespace std; 6 bool r[MAXN];//表示初始时第i个元素是否为record 7 int a[MAXN];//输入的数据 8 int x[MAXN];//移去值为i的元素后record总数的变化 9 int tree[MAXN];//树状数组 10 int n; 11 set<int> s; 12 13 void add(int i,int num) 14 { 15 for(int j=i;j<=n;j+=j&-j) tree[j]+=num; 16 } 17 18 int Sum(int i) 19 { 20 int result=0; 21 for(int j=i;j>0;j-=j&-j)result+=tree[j]; 22 return result; 23 } 24 25 int main() 26 { 27 cin>>n; 28 for(int i=1;i<=n;++i) 29 { 30 cin>>a[i]; 31 if((Sum(a[i]-1)==i-1)) 32 { 33 x[a[i]]--; 34 } 35 else if((Sum(a[i]-1)==i-2)) 36 { 37 x[*(s.lower_bound(a[i]))]++; 38 } 39 s.insert(a[i]); 40 add(a[i],1); 41 } 42 int ri=1,rmax=x[ri]; 43 for(int i=1;i<=n;++i) 44 { 45 if(x[i]>rmax) 46 { 47 ri=i; 48 rmax=x[i]; 49 } 50 } 51 cout<<ri<<endl; 52 }
结论
秒啊,学不会…