Codeforces Round #366 (Div. 2) C. Thor (模拟)*

本文解析了CodeForces竞赛中一道关于模拟未读消息处理的题目,详细介绍了三种操作的处理逻辑及其实现方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接:http://codeforces.com/contest/705/problem/C


题意:

input
4 6
1 2
1 4
1 2
3 3
1 3
1 3
output
1
2
3
0
1
2
以第二个样例为例,第一行n和q,n表示某手机有n个app,q表示下面有q个操作。

操作类型1:app x增加一条未读信息。

操作类型2:一次把app x的未读信息全部读完。

操作类型3:按照操作类型1添加的顺序,按顺序读t条信息,注意这t条信息可能有的已经读过。


问每次操作后剩多少条未读信息。


本来想用线段树搞,但是操作3怎么也想不出来怎么实现。后来发现模拟可以过,感觉这其中的逻辑不太好想,特别是操作2和操作3的关系,错了好几次之后终于过了。


#include <iostream> 
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAX_N = 300100;
//mes是把所有收到信息按顺序存入
//appms是指第i个app的所有信息数
//appr指第i个app的所有已读信息数
//read指操作3中第i个app读的信息数 
int mes[MAX_N], appm[MAX_N], appr[MAX_N], read[MAX_N];
int main() {
	int n, q, i, j;
	scanf("%d %d", &n, &q);
	//cnt指总信息数,last指操作3上一次读到了哪一条信息
	//p是数组mes的一个指针 
	int cnt = 0, ans = 0, last = 0, p = 0; 
	for(i = 0; i < q; i++) {
		int x, y;
		scanf("%d %d", &x, &y);
		if(x == 1) {
			mes[cnt++] = y;
			appm[y]++;
			ans++;
		}
		else if(x == 2) {
			ans -= appm[y] - appr[y]; //未读的就是全部的的减去已读的 
			appr[y] = appm[y];
		}
		else {
			if(last < y) { //若大于等于则读不到未读信息 
				for(; p < y; p++) {
					read[mes[p]]++;
					if(read[mes[p]] > appr[mes[p]]) { //读到了未读信息 
						ans -= read[mes[p]] - appr[mes[p]];
						appr[mes[p]] = read[mes[p]];
					}
				}
				last = y;//更新last 
			}
		}
		printf("%d\n", ans);
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值