Codeforces Round #484 (Div. 2) D. Shark

题面:

D. Shark
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

For long time scientists study the behavior of sharks. Sharks, as many other species, alternate short movements in a certain location and long movements between locations.

Max is a young biologist. For nn days he watched a specific shark, and now he knows the distance the shark traveled in each of the days. All the distances are distinct. Max wants to know now how many locations the shark visited. He assumed there is such an integer kk that if the shark in some day traveled the distance strictly less than kk, then it didn't change the location; otherwise, if in one day the shark traveled the distance greater than or equal to kk; then it was changing a location in that day. Note that it is possible that the shark changed a location for several consecutive days, in each of them the shark traveled the distance at least kk.

The shark never returned to the same location after it has moved from it. Thus, in the sequence of nn days we can find consecutive nonempty segments when the shark traveled the distance less than kk in each of the days: each such segment corresponds to one location. Max wants to choose such kk that the lengths of all such segments are equal.

Find such integer kk, that the number of locations is as large as possible. If there are several such kk, print the smallest one.

Input

The first line contains a single integer nn (1n1051≤n≤105) — the number of days.

The second line contains nn distinct positive integers a1,a2,,ana1,a2,…,an (1ai1091≤ai≤109) — the distance traveled in each of the day.

Output

Print a single integer kk, such that

  1. the shark was in each location the same number of days,
  2. the number of locations is maximum possible satisfying the first condition,
  3. kk is smallest possible satisfying the first and second conditions.
Examples
input
Copy
8
1 2 7 3 4 8 5 6
output
Copy
7
input
Copy
6
25 1 2 3 14 36
output
Copy
2
Note

In the first example the shark travels inside a location on days 11 and 22 (first location), then on 44-th and 55-th days (second location), then on 77-th and 88-th days (third location). There are three locations in total.

In the second example the shark only moves inside a location on the 22-nd day, so there is only one location.


题意:

有一只鲨鱼每天游ai公里,如果它一天游的距离大于等于k,我们就认为它游到了一个新的地方;否则认为它这一天停留在原来的地方。这只鲨鱼到过的地方不会重复。现在给出它n天游的距离(每天都不相等),我们要求出一个k,满足:

1.鲨鱼停留在每个地方的天数相等。(一天游的距离大于等于k时不算停留)。

2.停留过的地方尽可能多。

3.有多个解时k取最小值。


思路:

题目有点点绕,总之就是我们要确定一个k,使得小于k的子序列长度都是相等的,而且要尽可能多,最后保证k取最小值。根据第三个限制,我们可以想到最后的解一定是其中一个a的值加一

根据数据量显然需要O(nlgn)或者更低的复杂度。开始的时候想着二分或者贪心找最优解,分析了下样例发现这道题目的解不具有单调性,所以不可能二分,需要枚举每个k的可能解,找最优。那么我们就需要对每一天在lgn的时间内处理出它是否有解以及解的大小

忘了每一天的距离都不一样白白想了好久,基于每个a都不相同这个条件我们可以对a先递增排序,顺序处理的时候因为是从小到大,所以每次只需要增加一个满足条件的点即可。把这个点的标记置为1,分别判断它的左右是否标记过,如果标记过就连成一个区间。至于怎么判断每个区间是否相等,我们可以维护一个最大区间的长度,和所有区间的长度,我们还知道区间数量,所以有 最大长度*区间数量=总长度。通过这个公式就可以判断是否区间长度都相等。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<list>
#include<set>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<string>
#include<cstdlib>
#include<algorithm>
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int mod = 1000000009;
const int maxn = 100005;
map<int, int> mp;
int a[maxn], l[maxn], r[maxn];
bool vis[maxn];
int main(){
    int n;
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i){
        scanf("%d", &a[i]);
        mp[a[i]] = i;//map记录每个值原来的位置
    }
    sort(a + 1, a + n + 1);
    memset(vis, 0, sizeof(vis));
    int len = 0, ans = 0, p = a[n - 1] + 1, cnt = 0;
    for (int i = 1; i <= n; ++i) {
        int pos = mp[a[i]];
        vis[pos] = 1;
        if (vis[pos - 1] == 1 && vis[pos + 1] == 1) { //左右都标记过,就连成一片
            --cnt;
            r[l[pos - 1]] = r[pos + 1];//更新区间范围
            l[r[pos + 1]] = l[pos - 1];//更新区间范围
            r[pos] = r[pos + 1];
            l[pos] = l[pos - 1];
        } else if (vis[pos - 1] == 1) { //左边标记过
            l[pos] = l[pos - 1];
            r[pos] = pos;
            r[l[pos - 1]] = pos;
        } else if (vis[pos + 1] == 1) { //右边标记过
            r[pos] = r[pos + 1];
            l[pos] = pos;
            l[r[pos + 1]] = pos;
        } else { //产生一个新的区间
            ++cnt;
            l[pos] = pos;
            r[pos] = pos;
        }
        int ll = r[pos] - l[pos] + 1;
        if (ll > len) {
            len = ll;
        }
        if (len * cnt == i) { //是否每个区间长度都相等
            if (cnt > ans) {
                ans = cnt;
                p = a[i] + 1;
            }
        }
        //printf("%d %d %d %d\n", i, a[i], len, cnt);
    }
    printf("%d\n", p);
}
/*
8
1 2 8 3 4 9 5 6
*/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值