Bubble Cup 13 - Finals [Online Mirror, unrated, Div. 2]G. Years【差分+优先队列】

本文介绍了一种高效算法,用于解决在大规模时间范围内查找人口峰值的问题。通过使用差分思想和优先队列,该算法能在合理的时间复杂度内找到特定时间段内生存个体最多的年份及其数量。

题目

传送门
G. Years
time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
During one of the space missions, humans have found an evidence of previous life at one of the planets. They were lucky enough to find a book with birth and death years of each individual that had been living at this planet. What’s interesting is that these years are in the range (1,109)! Therefore, the planet was named Longlifer.

In order to learn more about Longlifer’s previous population, scientists need to determine the year with maximum number of individuals that were alive, as well as the number of alive individuals in that year. Your task is to help scientists solve this problem!

Input
The first line contains an integer n (1≤n≤105) — the number of people.

Each of the following n lines contain two integers b and d (1≤b<d≤109) representing birth and death year (respectively) of each individual.

Output
Print two integer numbers separated by blank character, y — the year with a maximum number of people alive and k — the number of people alive in year y.

In the case of multiple possible solutions, print the solution with minimum year.

输入
3
1 5
2 4
5 6
输出
2 2
输入
4
3 4
4 5
4 6
8 10
输出
4 2

题意:给出n个范围,每个范围[l,r)表示一个人活着的范围,求哪一年活着的人最多,最多有多少人

思路:范围是1e9,如果用差分再跑一遍范围找最大值的话绝对超时,所以们我们不可能开数组跑,但是可以用差分的思想,我们定义一个成对数类型,第一个数存每个范围的开头或结尾数字,第二个数字存1或-1,按照第一个数从小到大排序,相加最后加一下求最大值即可.具体看代码

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<map>
#include<queue>
#include<stack>
#include<sstream>
using namespace std;
 int t,m,n;
 typedef pair<int,int>p;//成对数
 priority_queue<p,vector<p>,greater<p>>que;//优先队列,第一个数优先从小到大排序,第一个数相同的话,第二个数从小到大排序
void solve()
{
    while(!que.empty())
        que.pop();
    int a,b;
    cin>>n;
for(int i=0;i<n;i++)
{
   cin>>a>>b;
   que.push(make_pair(a,1));//范围开头的数第二个数存1
    que.push(make_pair(b,-1));//范围结尾的数第二个数存-1
}
int ans=0,maxx=0,o=0;
while(!que.empty())
     {
         p g=que.top();
         que.pop();
         maxx+=g.second;//
         if(maxx>ans)//求最大值
         {
             ans=maxx;//人数
             o=g.first;//年份
         }
     }
     printf("%d %d\n",o,ans);
}
int main()
{
     solve();
 
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值