codeforces 18-05-18 D Shark

(1)题意:
D:鲨鱼
很长时间以来科学家研究鲨鱼的行为。鲨鱼,像其他生物物种一样,它轮流的在短时间内在固定的一个地方,长时间内在一些地方之间。
Max是一名年轻的生物学家。在n天内他观察到一个特殊的鲨鱼,而且现在他知道在这n天的时间里鲨鱼每天游走的距离。这些距离都不相等。Max想知道有多少地域是鲨鱼已经去过的。他假设一个整数k,这些鲨鱼在某些天内可能游走的距离确实小于k,那么就不改变它游走的区域。否则,如果有一天鲨鱼游走的距离大于或等于k,那么它将改变它游走的区域。注意在连续的一段时间内,鲨鱼有可能改变一个区域,在这段时间内,鲨鱼游走的距离至少是k。
这个鲨鱼从不返回同样的区域如果它以前来过这里。因此,当鲨鱼在连续的n天内游走的距离少于k,我们可以在这n天内找到一段连续非空的部分。每个部分对应一个区域。Max想要选择这个k使这些部分可以相等。
找到这个证书k,使得鲨鱼游走的区域尽可能的多。如果存在多种可能的k值,则输出最小的那一个。
输入:
第一行包含一个整数n(1~1e5)表示天数。
第二行包含n个互不相等的正整数a1,a2,a3…an(1~1e9)鲨鱼每天有走的距离。
输出:
输出一个整数k满足:
1, 在相同天数内鲨鱼在同一个地方。
2, 在满足第一个条件的情况下,这些区域的数量最大。
3, K是满足情况的k值中最小的在满足第一个和第二个条件的情况下。
提示:
在第一个样例中,这个鲨鱼在同一个区域(在第一天和第二天),其次,在第四天和第五天它在第二个区域,其三第7天和地8天它在第三个区域内。一共有三区域。
在第二个样例中,这个鲨鱼仅仅在第二天在一个区域内移动,因此只存在一个区域。
(2)题目链接:http://codeforces.com/contest/982/problem/D
(3)通过的代码:

#include<cstdio>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
const int N=1e5+7;
int n,m,fa[N],a[N],val[N],p,ans,id,b[N],size[N];
multiset<int>s;map<int,int>e;
int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}
int main(){
    for(int i=0;i<N;i++)fa[i]=i,size[i]=1;//并查集初始化,并查集的修改区间的方法的初始化。 
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%d",a+i),b[i]=a[i];//用b数组同时存a数组中的数据。 
    sort(b+1,b+n+1);// 对b数组中的数据进行排序。 
    for(int i=1;i<=n;i++)
        a[i]=lower_bound(b+1,b+n+1,a[i])-b,e[a[i]]=i;
        //a[i]更新为原来的a[i]在b数组中的位置。e[原a[i]在b数组中的位置]插入当前位置。 
    for(int i=1;i<=n;i++){
        int x=e[i];
        if(val[x])s.erase(s.lower_bound(val[x]));
        p=find(x-1);//p用来查找x前面没有用过的点。 
        size[p]+=size[x];
        if(val[p])s.erase(s.lower_bound(val[p]));
        fa[x]=p;
        s.insert(size[p]-1);
        val[p]=size[p]-1;
        if(s.size()>ans&&*s.begin()==*s.rbegin()){
            ans=s.size();id=b[i]+1;
        }
    }
    printf("%d\n",id);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值