zoukankan      html  css  js  c++  java
  • Codeforces 982D (带权并查集)

    传送门

    题面:

    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.

    题目描述:

        给你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;
    }
    


  • 相关阅读:
    Mybatis的XML中数字不为空的判断
    初步使用VUE
    Vue中实现菜单下拉、收起的动画效果
    Docker For Windows时间不对的问题
    freemarker使用自定义的模板加载器通过redis加载模板
    .net core 打印请求和响应的内容
    codedecision P1113 同颜色询问 题解 线段树动态开点
    洛谷P2486 [SDOI2011]染色 题解 树链剖分+线段树
    洛谷P3150 pb的游戏(1)题解 博弈论入门
    codedecision P1112 区间连续段 题解 线段树
  • 原文地址:https://www.cnblogs.com/Chen-Jr/p/11007286.html
Copyright © 2011-2022 走看看