Codeforces 982D (带权并查集)
题面:
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.
The first line contains a single integer nn (1≤n≤1051≤n≤105) — the number of days.
The second line contains nn distinct positive integers a1,a2,…,ana1,a2,…,an (1≤ai≤1091≤ai≤109) — the distance traveled in each of the day.
Print a single integer kk, such that
- the shark was in each location the same number of days,
- the number of locations is maximum possible satisfying the first condition,
- kk is smallest possible satisfying the first and second conditions.
8 1 2 7 3 4 8 5 6
7
6 25 1 2 3 14 36
2
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.
题目描述:
给你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;
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;
}
}
}
cout<<ans<<endl;
return 0;
}