180516海港题解

题目描述

小 K 是一个海港的海关工作人员,每天都有许多船只到达海港,船上通常有很多来自不同国家的乘客。

小 K 对这些到达海港的船只非常感兴趣,他按照时间记录下了到达海港的每一艘船只情况;对于第 ii 艘到达的船,他记录了这艘船到达的时间 t_iti​ (单位:秒),船上的乘客数 k_iki​,以及每名乘客的国籍 x_{i,1}, x_{i,2},\dots,x_{i,k}xi,1​,xi,2​,…,xi,k​。

小K统计了 n 艘船的信息,希望你帮忙计算出以每一艘船到达时间为止的 24 小时(24 小时 =86400=86400 秒)内所有乘船到达的乘客来自多少个不同的国家。

形式化地讲,你需要计算 nn 条信息。对于输出的第 ii 条信息,你需要统计满足 t_i-86400<t_p \le t_iti​−86400<tp​≤ti​ 的船只 pp,在所有的 x_{p,j}xp,j​

 中,总共有多少个不同的数

输入格式

第一行输入一个正整数 nn,表示小 K 统计了 nn 艘船的信息。

接下来 nn 行,每行描述一艘船的信息:前两个整数 t_iti​ 和 k_iki​ 分别表示这艘船到达海港的时间和船上的乘客数量,接下来 k_iki​ 个整数 x_{i,j}xi,j​ 表示船上乘客的国籍。

保证输入的 t_iti​ 是递增的,单位是秒;表示从小K第一次上班开始计时,这艘船在第 t_iti​ 秒到达海港。

保证 1 \le n \le 10^51≤n≤105,\sum{k_i} \le 3\times 10^5∑ki​≤3×105 ,1\le x_{i,j} \le 10^51≤xi,j​≤105, 1 \le t_{i-1}\le t_i \le 10^91≤ti−1​≤ti​≤109。

其中 \sum{k_i}∑ki​ 表示所有的 k_iki​ 的和。

输出格式

输出n行,第i行输出一个整数表示第i艘船到达后的统计信息。

样例输入

3
1 4 4 1 2 2
2 2 2 3
10 1 3

样例输出

3
4
4

样例输入

4
1 4 1 2 2 3
3 2 2 3
86401 2 3 4
86402 1 5

样例输出

3
3
3
4

问题提示

【样例1说明】

第一艘船在第1秒到达海港,最近24小时到达的船是第一艘船,共有4个乘客,分别是来自国家4、1、2、2,共来自3个不同的国家;

第二艘船在第2秒到达海港,最近24小时到达的船是第一艘船和第二艘船,共有4+2=6个乘客,分别是来自国家4、1、2、2、2、3,共来自4个不同的国家;

第三艘船在第10秒到达海港,最近24小时到达的船是第一艘船、第二艘船和第三艘船,共有4+2+1=7个乘客,分别是来自国家4、1、2、2、2、3、3,共来自4个不同的国家。

【样例2说明】

第一艘船在第1秒到达海港,最近24小时到达的船是第一艘船,共有4个乘客,分别是来自国家1、2、2、3,共来自3个不同的国家;

第二艘船在第3秒到达海港,最近24小时到达的船是第一艘船和第二艘船,共有4+2=6个乘客,分别是来自国家1、2、2、3、2、3,共来自3个不同的国家;

第三艘船是在第86401秒到达海港,最近24小时到达的船是第二艘船和第三艘船,共有2+2=4个乘客,分别是来自国家2、3、3、4,共来自3个不同的国家;

第四艘船在第86402秒到达海港,最近24小时到达的船是第二艘船、第三艘船和第四艘船,共有2+2+1=5个乘客,分别是来自国家2、3、3、4、5,共来自4个不同的国家。

思路

运用尺取法,求解24小时内所有不同的国籍,详细解释见代码

程序实现

#include <iostream>
#include <queue>
#include <cstdio>
using namespace std;
#define int long long
#define F(i,a,b) for(int i=(a);i<=(b);i++)
#define R(i,a,b) for(int i=(a);i>=(b);i--)
const int N=1e5+5;
int n,k,t,x,ans;
int cnt[N];
//定义结构体,存储时间与国籍 
struct Node
{
	int t,x;
};
//队列记录符合条件的时间与国籍 
queue<Node> q;
signed main()
{
	//读入数据 
	scanf("%lld",&n);
	//从一到n遍历第i艘船到达时间为止的24小时内所有乘船到达的乘客来自多少个不同的国家 
	F(i,1,n)
	{
		//读入数据 
		scanf("%lld%lld",&t,&k);
		F(j,1,k)
		{
			cin>>x;
			//哈希记录此国籍
			cnt[x]++;
			//如果是新国籍,ans加一 
			if(cnt[x]==1) ans++;
			//将国际与时间读入队列 
			q.push(Node{t,x});
		}
		//如果队不空且第一个时间与最后一个时间差>=24时时,将此时间与国籍弹出队列 
		while(!q.empty() && q.front().t+86400<=t)
		{
			//将此国籍的数量减一 
			cnt[q.front().x]--;
			//如果此国籍没有了,ans减一 
			if(cnt[q.front().x]==0) ans--;
			//将此时间与国籍弹出队列 
			q.pop();
		}
		//输出答案 
		cout<<ans<<"\n";
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值