题意:给你一个长度为n的数组,你可以经过随意的排序,让你求数组前缀和后缀的最长递增子序列 的最小值 的最大值。
思路:因为要求前缀和后缀的最长子序列,
并且后缀数组的最长递增子序列就是原数组的最长递减子序列,显然,这两个最多只
能有一个下标的交集。
那么对于出现超过两次的数字,可以一个放在上升子序列中,一个放在下降子序列中,然后超过两次的数字就可以直接去除。
对于只出现了一次的数,因为上升和下降序列的最多 的公共交集只能为1,那么就加上)出现一次的数 +1)/2为最后的结果。
/**
* ┏┓ ┏┓+ +
* ┏┛┻━━━┛┻┓ + +
* ┃ ┃
* ┃ ━ ┃ ++ + + +
* ████━████+
* ◥██◤ ◥██◤ +
* ┃ ┻ ┃
* ┃ ┃ + +
* ┗━┓ ┏━┛
* ┃ ┃ + + + +Code is far away from
* ┃ ┃ + bug with the animal protecting
* ┃ ┗━━━┓ 神兽保佑,代码无bug
* ┃ ┣┓
* ┃ ┏┛
* ┗┓┓┏━┳┓┏┛ + + + +
* ┃┫┫ ┃┫┫
* ┗┻┛ ┗┻┛+ + + +
*/
#include<cstdio>
#include <iostream>
#include <algorithm>
#include <string.h>
#include <string>
#include <math.h>
#include<vector>
#include<queue>
#include<map>
#define sc_int(x) scanf("%d", &x)
#define sc_ll(x) scanf("%lld", &x)
#define pr_ll(x) printf("%lld", x)
#define pr_ll_n(x) printf("%lld\n", x)
#define pr_int_n(x) printf("%d\n", x)
#define ll long long
using namespace std;
const int N=1000000+100;
int n ,m,h;
int s[N];
map<int,int>q;
int main()
{
int t;
sc_int(t);
while(t--)
{
q.clear();
cin>>n;
for(int i =1;i<=n;i++)
cin>>s[i];
int sum=0,summ=0;
for(int i =1;i<=n;i++)
{
if(!q[s[i]])sum++;
q[s[i]]++;
if(q[s[i]]==2)
sum++;
}
cout<<(sum+1)/2<<endl;
}
return 0;
}