ICPC Southeast USA 2020 Regional Contest Problem P Unread Messages

6 篇文章 0 订阅

P Unread Messages

There is a group of people in an internet email message group. Messages are sent to all members
of the group, and no two messages are sent at the same time.

Immediately before a person sends a message, they read all their unread messages up to that point.
Each sender also reads their own message the moment it is sent. Therefore, a person’s unread
messages are exactly the set of messages sent after that person’s last message.

Each time a message is sent, compute the total number of unread messages over all group members.

Input

The first line of input contains two integers n (1 ≤ n ≤ 10^9
) and m (1 ≤ m ≤ 1,000), where n is
the number of people in the group, and m is the number of messages sent. The group members are
identified by number, 1 through n.

Each of the next m lines contains a single integer s (1 ≤ s ≤ n), which is the sender of that
message. These lines are in chronological order.

Output

Output m lines, each with a single integer, indicating the total number of unread messages over all
group members, immediately after each message is sent.

Sample Input 1

2 4
1
2
1
2

Sample Output 1

1
1
1
1

Sample Input 2

3 9
1
2
3
2
1
3
3
2
1

Sample Output 2

2
3
3
4
3
3
5
4
3

题目大意:

有n个人互相发送电子邮件,当一个人给别人发送电子邮件时,其他所有人的未读邮件数量会加1,自己的未读邮件数量清0。

题目给定m个发送邮件的编号(1 - n)表示发送邮件的人,对于每一个发送邮件的编号,输出当时所有人的未读邮件数量之和。

题解:

这道题的人数有1e9,数组是存不下的,所以没办法用暴力来模拟发邮件过程,而发邮件的数量只有m(1 - 1000),发邮件的人最多也只有1000人,所以我们只需要记录m个人的发邮件时间即可。

每当有一个人发送了邮件,就会产生n - 1封未读邮件,总数sum += n - 1,同时发件人要清空自己的未读邮件。

在 i = 1到 i = m的循环中发件人的未读邮件的数量就等于(当前 i - (上一次发送邮件的 i) - 1)。我们可以用map来记录每个编号上一次发件时 i 为多少,再和现在的 i 比较来确定减少了多少未读邮件数量, 再用sum -= (i - mp[x] - 1)来减少未读邮件数量。

注意本题数据量较大,要开long long。

AC代码:

#include <iostream>
#include <map>
using namespace std;
typedef long long ll;
const int N = 1e6 + 5;
int main() {
    ios::sync_with_stdio(false);
	ll n, m, sum = 0;
	cin >> n >> m;
	map<ll, ll> mp;
	for (ll i = 1; i <= m; i ++) {
		ll s;
		cin >> s;
		sum += n - 1; // 发邮件会产生n - 1封未读邮件 
		sum -= (i - mp[s] - 1); // 发件人的未读邮件清空,未读邮件=当前i - 上一次发信i - 1 
		cout << sum << '\n'; // 输出未读邮件总数 
		mp[s] = i; // 更新发件人上一次发信时间 
	}
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值