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
*/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章