链接:https://ac.nowcoder.com/acm/contest/3886/I
来源:牛客网
题目描述
小K是一个海港的海关工作人员,每天都有许多船只到达海港,船上通常有很多来自不同国家的乘客。
小K对这些到达海港的船只非常感兴趣,他按照时间记录下了到达海港的每一艘船只情况;对于第i艘到达的船,他记录了这艘船到达的时间ti (单位:秒),船上的乘客数ki,以及每名乘客的国籍 xi,1, xi,2,…,xi,ki。
小K统计了n艘船的信息,希望你帮忙计算出以每一艘船到达时间为止的24小时(24小时=86400秒)内所有乘船到达的乘客来自多少个不同的国家。
形式化地讲,你需要计算n条信息。对于输出的第i条信息,你需要统计满足 ti - 86400 < tp <= ti的船只p,在所有的xp,j中,总共有多少个不同的数。
输入描述:
第一行输入一个正整数n,表示小K统计了 n艘船的信息。
接下来n行,每行描述一艘船的信息:前两个整数ti和ki分别表示这艘船到达海港的时间和船上的乘客数量,接下来ki个整数x(i,j)表示船上乘客的国籍。
保证输入的ti是递增的,单位是秒;表示从小K第一次上班开始计时,这艘船在第ti秒到达海港。
保证 1 ≤ n ≤ 105 , ∑ki\sum{k_i}∑ki ≤ 3*10^5, 1≤ x(i,j) ≤ 105 , 1 ≤ t(i-1)≤ ti ≤ 109 。
其中 ∑ki\sum{k_i}∑ki 表示所有的ki的和。
输出描述:
输出n行,第i行输出一个整数表示第i艘船到达后的统计信息。
示例1
示例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个不同的国家。
备注:
思路
考虑到数据量的问题, 枚举 t 是不可能的,考虑每艘船的到岸时间是递增的,可以用一个 deque 来保存每艘船上人的国籍和随船到达时间。
对于每艘相邻到达的船,如果时间相距大于一天时就让所有上一艘船上的人下船并更新 tot 数组和 ans 。
CODE
#include <bits/stdc++.h> #define dbg(x) cout << #x << "=" << x << endl #define eps 1e-8 #define pi acos(-1.0) using namespace std; typedef long long LL; template<class T>inline void read(T &res) { char c;T flag=1; while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0'; while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag; } namespace _buff { const size_t BUFF = 1 << 19; char ibuf[BUFF], *ib = ibuf, *ie = ibuf; char getc() { if (ib == ie) { ib = ibuf; ie = ibuf + fread(ibuf, 1, BUFF, stdin); } return ib == ie ? -1 : *ib++; } } int qread() { using namespace _buff; int ret = 0; bool pos = true; char c = getc(); for (; (c < '0' || c > '9') && c != '-'; c = getc()) { assert(~c); } if (c == '-') { pos = false; c = getc(); } for (; c >= '0' && c <= '9'; c = getc()) { ret = (ret << 3) + (ret << 1) + (c ^ 48); } return pos ? ret : -ret; } struct node{ int t, x; }; int tot[300005]; deque<node> q; int main() { int n; scanf("%d",&n); int ans = 0; for ( int i = 1; i <= n; ++i ) { int t, k; scanf("%d %d",&t, &k); for ( int j = 1; j <= k; ++j ) { int x; scanf("%d",&x); if(tot[x] == 0) ans++; tot[x]++; q.push_back({t,x}); } while(t - q.front().t > 86400) { tot[q.front().x]--; if(!tot[q.front().x]) { ans--; } q.pop_front(); } cout << ans << endl; } return 0; }