Shark CodeForces - 982D(解法二:并查集)

                                        转自: https://blog.csdn.net/weixin_39453270/article/details/80391161

 
 

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.

扫描二维码关注公众号,回复: 1445968 查看本文章

题目描述:

    给你N个数字的一个数列,每个数字表示鲨鱼在第i天的活动距离。

    假设鲨鱼活动的距离小于k则不会移动位置 不小于则移动(移动是单方向的 不会回去)

    询问你找一个最小的k使得位置的数量最大且同时鲨鱼在每个位置的天数相同

题目分析:

    因为我们要使位置的数量最大,且要每个位置的天数相同,因此,我们可以把每个位置看作一个集合,从而把对数组的操作转化成集合的操作,这样我们就可以通过并查集进行维护了。

    具体我们首先我们要将步数从小到大排序(记录好下标),进而进行遍历。如果它两边有比它小的数就用并查集把它俩并起来 同时维护好并查集的大小。

    如果碰到满足该并查集大小*并查集内元素数目等于现在遍历到的总数目 就是合法的 尝试更新答案,具体描述代码中有

#include <bits/stdc++.h>
#define maxn 100005
using namespace std;
typedef pair<int,int>PLL;
const int MAXN=100005;
int sum[maxn];//表示以第i位置及其两边不大于它的连续的数的集合的大小
int cntsum[maxn];//大小为i的集合数量有几个
int n,a[maxn],ans,Far[maxn],cnt;
PLL b[maxn];
int Find_F(int x) {//路径压缩
    if(x==Far[x]) return x;
    else return Far[x]=Find_F(Far[x]);
}
void unite(int x,int y){//将y合并成x
    x=Find_F(x);
    y=Find_F(y);
    cntsum[sum[x]]--,cntsum[sum[y]]--;//合并之后这两种长度的区间都会减少一个
    sum[x]+=sum[y];
    Far[y]=x;
    cntsum[sum[x]]++;//而他们之和的长度的区间则会增加一个
    cnt--;
}
int main() {
    cin>>n;
    for(int i=1;i<=n;++i) {
        cin>>a[i];
        b[i].first=a[i];
        b[i].second=i;
        Far[i]=i;
    }
    sort(b+1,b+n+1);
    int mx=0,ans=0;//mx 记录最大区间个数
    for(int i=1;i<=n;++i) {
        int x=b[i].second;
        int y=b[i].first;
        sum[x]=1;//初始化为1.
        cntsum[1]++;//集合数量为1的集合+1
        cnt++;//记录合并的次数,就是分成区间的个数
        if(x!=n&&a[x+1]<a[x])//当前的数大于后一位
            unite(x,x+1);
        if(x!=1&&a[x-1]<a[x])//当前的数小于后一位
            unite(x-1,x);
        if(cnt==cntsum[sum[Find_F(x)]]){//如果分成区间个数和该长度的区间个数相同
            if(cnt>mx) {//并且区间个数要大于最大区间个数,则更新!
                mx=cnt;
                ans=y+1;//应为我们要越过y所以,答案要是y+1!而不是y。
            }
        }
    }
    cout<<ans<<endl;
    return 0;
}


猜你喜欢

转载自blog.csdn.net/qq_41874469/article/details/80512383