时间限制: 1000MS
空间限制: 128MB
给定含有
n
n
n 个元素的多重集合
S
S
S,每个元素在
S
S
S 中出现的次数称为
题目描述:
该元素的重数。多重集
S
S
S中重数最大的元素称为众数。
例如,
S
=
{
1
,
2
,
2
,
2
,
3
,
5
}
S= \{1,2,2,2,3,5 \}
S={1,2,2,2,3,5}。多重集
S
S
S 的众数是2,其重数为3。
对于给定的由
n
n
n 个自然数组成的多重 集
S
S
S,计算
S
S
S 的众数及其重数。
输入描述:
第 1 行多重集 S S S 中元素个数 n n n ;接下来的 n n n 行中,每行有一个自然数。保证 n ≤ 2 × 1 0 6 , s i ≤ 1 0 9 n \le 2 \times 10^6,s_i \le10^9 n≤2×106,si≤109
输出描述:
第 1 行给出众数,第 2 行是重数。
样例:
输入:
6
1
2
2
2
3
5
输出:
2
5
分析:
对于这种问题的时间复杂度来说,排一下序找一下最长的连续数集就能通过这个问题,时间复杂度为排序的 O ( n l o g n + n ) O(nlogn+n) O(nlogn+n) ,当然既然我们是学算法的,那我们就需要优化一下这个时间复杂度。
排序分治求解:
首先我们对一个有序的序列,以分治的思想来处理这个问题
此时我们可以将查找最长连续数集的时间复杂度由
O
(
n
)
O(n)
O(n) 优化到
O
(
l
o
g
n
)
O(logn)
O(logn),当然排序带来的影响是的总体时间复杂度还是
O
(
n
l
o
g
n
+
l
o
g
n
)
O(nlogn+logn)
O(nlogn+logn)
当然由一个小优化点就是对于长度小于当前最长数集长的数集可以剪一下枝。
代码实现:
#include <bits/stdc++.h>
using namespace std;
#define all(x) x.begin(), x.end()
#define al(a, b) a, a + b
#define bit1(x) __builtin_popcount(x)
#define Pqueue priority_queue
#define lc p << 1
#define rc p << 1 | 1
#define IOS ios::sync_with_stdio(false), cin.tie(0);
#define fi first
#define se second
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair<ll, ll> PII;
const ll mod = 1000000007;
const ll N = 2e6 + 10;
const ld eps = 1e-9;
const ll inf = 1e18;
const ll P = 131;
const ll dir[8][2] = {1, 0, 0, 1, -1, 0, 0, -1, 1, 1, 1, -1, -1, 1, -1, -1};
int n, s[N];
int find_l(int *a, int x)
{
return lower_bound(al(a + 1, n), x) - a;
}
int find_r(int *a, int x)
{
return upper_bound(al(a + 1, n), x) - a - 1;
}
int mx_num, mx;
void get_max_num(int l, int r)
{
if (l == r)
{
if (mx_num == 0)
{
mx_num = 1;
mx = s[l];
}
return;
}
int mid = l + r >> 1;
int lft = find_l(s, s[mid]);
int rgt = find_r(s, s[mid]);
if (mx_num < rgt - lft + 1)
{
mx_num = rgt - lft + 1;
mx = s[mid];
}
if (lft - l > mx_num)
get_max_num(l, lft - 1);
if (r - rgt > mx_num)
get_max_num(rgt + 1, r);
}
void solve()
{
cin >> n;
for (int i = 1; i <= n; i++)
cin >> s[i];
sort(al(s + 1, n));
// for (int i = 1; i <= n; i++)
// cout << s[i] << " \n"[i == n];
get_max_num(1, n);
cout << mx << "\n"
<< mx_num;
}
int main()
{
IOS int T = 1;
// cin>>T;
while (T--)
solve();
return 0;
}
/*
oxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxox
x o
o _/_/_/_/ _/ x
x _/ o
o _/_/_/_/ _/ _/_/ _/_/ _/_/_/ _/_/ _/_/_/ _/_/ _/_/_/ _/ _/ _/ x
x _/ _/_/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ o
o _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/_/ x
x _/ _/ _/_/ _/ _/ _/ _/_/_/ _/_/ _/ _/ _/ _/ _/ o
o _/ _/ _/ x
x _/ _/_/ _/ o
o x
xoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxo
*/
非排序分治求解:
对于非排序的分治求解,其实是套用一下快速排序的思想,取一个基准值,之后按照一遍排序之后,找一下基准值对应的数集的长度,之后递归求解一下。时间复杂度完全优化到
O
(
n
l
o
g
n
)
O(nlogn)
O(nlogn)。
代码实现:
#include <bits/stdc++.h>
using namespace std;
#define all(x) x.begin(), x.end()
#define bit1(x) __builtin_popcount(x)
#define Pqueue priority_queue
#define lc p << 1
#define rc p << 1 | 1
#define IOS ios::sync_with_stdio(false), cin.tie(0);
#define fi first
#define se second
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair<ll, ll> PII;
const ll mod = 1000000007;
const ll N = 1e6 + 10;
const ld eps = 1e-9;
const ll inf = 1e18;
const ll P = 131;
const ll dir[8][2] = {1, 0, 0, 1, -1, 0, 0, -1, 1, 1, 1, -1, -1, 1, -1, -1};
int n, s[N << 1];
int mx, mx_num;
void quick_get_maxnum(int l, int r)
{
if (r - l + 1 <= mx_num)
return;
if (l == r)
return;
int lab = s[l];
int lft = l, rgt = r;
while (lft != rgt)
{
while (lft != rgt && s[rgt] > lab)
rgt--;
s[lft] = s[rgt];
while (lft != rgt && s[lft] <= lab)
lft++;
s[rgt] = s[lft];
}
s[lft] = lab;
int num = 0;
for (int i = l; i <= r; i++)
if (s[i] == lab)
num++;
if (mx_num < num)
{
mx_num = num;
mx = lab;
}
quick_get_maxnum(l, lft - 1);
quick_get_maxnum(rgt + 1, r);
}
void solve()
{
cin >> n;
for (int i = 1; i <= n; i++)
cin >> s[i];
quick_get_maxnum(1, n);
// for (int i = 1; i <= n; i++)
// cout << s[i] << " \n"[i == n];
cout << mx << "\n"
<< mx_num << "\n";
}
int main()
{
IOS int T = 1;
// cin>>T;
while (T--)
solve();
return 0;
}
/*
oxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxox
x o
o _/_/_/_/ _/ x
x _/ o
o _/_/_/_/ _/ _/_/ _/_/ _/_/_/ _/_/ _/_/_/ _/_/ _/_/_/ _/ _/ _/ x
x _/ _/_/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ o
o _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/_/ x
x _/ _/ _/_/ _/ _/ _/ _/_/_/ _/_/ _/ _/ _/ _/ _/ o
o _/ _/ _/ x
x _/ _/_/ _/ o
o x
xoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxo
*/