时间限制:C/C++ 5秒,其他语言10秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
We define an element in a sequence "good", if and only if there exists (1≤j<i) such that .
Given a permutation p of integers from 1 to n. Remove an element from the permutation such that the number of "good" elements is maximized.
输入描述:
The input consists of several test cases. The first line of the input gives the number of test cases,. For each test case, the first line contains an integer , representing the length of the given permutation. The second line contains n integersp1,p2,…,pn , representing the given permutation p. It's guaranteed that .
输出描述:
For each test case, output one integer in a single line, representing the element that should be deleted. If there are several answers, output the minimal one.
题意:给你一个长度为n(n<=1e6)的整数序列,定义“好数”:存在下标比它小的数,值也严格小于它。
你现在必须要删除且只能删除一个数,使删除后好数数量最多,如果有多个答案,输出最小的那个。
思路:只需要维护最小值和次小值,O(n)扫一遍即可。
至于为什么:因为我们为什么只需要维护最小值和次小值,是因为一个数一旦前面有超过两个比它小的数,那么只能删除该数才能使好数数量减少。(因为它本身就是一个好数)
因此定义一个权值数组c[i]表示数i删除后减少的好数的数量。
维护最小值mi和次小值mm,初始化均为inf然后每输入一个数:
1、a<mi 则mm=mi,mi=a;
2、a>=mi&&a<mm 则c[a]++,c[mi]++,mm=a;
3、a>=mm 则c[a]++;
最后找c[i]最小的i即可,多个相同的取最小的。
代码:
#include<bits/stdc++.h> #define ll long long using namespace std; const int maxn=1000010; const int inf=0x3f3f3f3f; int n,m,k; int ans,tmp,f,mm,mi; int a; int c[maxn]; bool flag; int main() { int T,cas=1; scanf("%d",&T); while(T--) { scanf("%d",&n); mm=inf,mi=inf; for(int i=1;i<=n;i++) c[i]=0; for(int i=1;i<=n;i++) { scanf("%d",&a); if(a<=mi) { mm=mi; mi=a; } else if(a>=mi&&a<mm) { c[mi]++; c[a]++; mm=a;//正式赛的时候因为漏写了这一句,最后也没通过,真是日了狗了!!! } else if(a>=mm) { c[a]++; } } ans=inf,tmp=mi; for(int i=1;i<=n;i++) { if(c[i]<ans) { ans=c[i]; tmp=i; } } printf("%d\n",tmp); } }