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;
}