时间限制: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);
}
}