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

C. Thor

time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Thor is getting used to the Earth. As a gift Loki gave him a smartphone. There are n applications on this phone. Thor is fascinated by this phone. He has only one minor issue: he can’t count the number of unread notifications generated by those applications (maybe Loki put a curse on it so he can’t).

q events are about to happen (in chronological order). They are of three types:

Application x generates a notification (this new notification is unread).
Thor reads all notifications generated so far by application x (he may re-read some notifications).
Thor reads the first t notifications generated by phone applications (notifications generated in first t events of the first type). It's guaranteed that there were at least t events of the first type before this event. Please note that he doesn't read first t unread notifications, he just reads the very first t notifications generated on his phone and he may re-read some of them in this operation. 

Please help Thor and tell him the number of unread notifications after each event. You may assume that initially there are no notifications in the phone.
Input

The first line of input contains two integers n and q (1 ≤ n, q ≤ 300 000) — the number of applications and the number of events to happen.

The next q lines contain the events. The i-th of these lines starts with an integer typei — type of the i-th event. If typei = 1 or typei = 2 then it is followed by an integer xi. Otherwise it is followed by an integer ti (1 ≤ typei ≤ 3, 1 ≤ xi ≤ n, 1 ≤ ti ≤ q).
Output

Print the number of unread notifications after each event.
Examples
Input

3 4
1 3
1 1
1 2
2 3

Output

1
2
3
2

Input

4 6
1 2
1 4
1 2
3 3
1 3
1 3

Output

1
2
3
0
1
2

Note

In the first sample:

Application 3 generates a notification (there is 1 unread notification).
Application 1 generates a notification (there are 2 unread notifications).
Application 2 generates a notification (there are 3 unread notifications).
Thor reads the notification generated by application 3, there are 2 unread notifications left. 

In the second sample test:

Application 2 generates a notification (there is 1 unread notification).
Application 4 generates a notification (there are 2 unread notifications).
Application 2 generates a notification (there are 3 unread notifications).
Thor reads first three notifications and since there are only three of them so far, there will be no unread notification left.
Application 3 generates a notification (there is 1 unread notification).
Application 3 generates a notification (there are 2 unread notifications). 

题意:有 n 个应用,然后有m个操作,操作分为三种:
1 x:向 x 应用发送一条信息
2 x :阅读x应用的信息
3 x: 阅读前 x <script id="MathJax-Element-929" type="math/tex">x</script>条信息
输出每次操作后未阅读的信息数

思路:我们可以用队列模拟,通过对应用进行标记,来进行,具体看代码。

ac代码:

/* ***********************************************
Author       : AnICoo1
Created Time : 2016-08-20-16.08 Saturday
File Name    : D:\MyCode\2016-8ÔÂ\2016-8-20.cpp
LANGUAGE     : C++
Copyright  2016 clh All Rights Reserved
************************************************ */
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<stack>
#include<set>
#include<map>
#include<queue>
#include<vector>
#include<iostream>
#include<algorithm>
#define MAXN 1010000
#define LL long long
#define ll __int64
#define INF 0xfffffff
#define mem(x,y) memset(x,(y),sizeof(x))
#define PI acos(-1)
#define gn (sqrt(5.0)+1)/2
#define eps 1e-8
using namespace std;
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
ll powmod(ll a,ll b,ll MOD){ll ans=1;while(b){if(b%2)ans=ans*a%MOD;a=a*a%MOD;b/=2;}return ans;}
double dpow(double a,ll b){double ans=1.0;while(b){if(b%2)ans=ans*a;a=a*a;b/=2;}return ans;}
//head
int cnt[MAXN];//队列中记录i应用接受到的信息数量
int use;//队列中被阅读过的信息数量
int used[MAXN];//队列中被阅读的i应用接收到的信息数量
int main()
{
    queue<int>q;mem(used,0);mem(cnt,0);use=0;
    int num=0;//总共接受的信息的数量
    int n,m;cin>>n>>m;
    for(int i=1;i<=m;i++)
    {
        int a,b;cin>>a>>b;
        if(a==1)
            q.push(b),cnt[b]++,num++;
        else if(a==2)
        {
        //如果队列中存在b应用没有阅读的信息,那么更新
            if(cnt[b]>used[b])
                use+=abs(cnt[b]-used[b]);
            used[b]=cnt[b];
        }
        else if(a==3)
        {
            if(num-q.size()<b)//如果前b个信息中存在没有阅读过的信息,那么开始出队
            {
                int k=0;b-=(num-q.size());//需要弹出的数量改变
                while(!q.empty()&&k<b)
                {
                    int x=q.front();q.pop();
                    if(used[x]>0)
                    {
                        use--;used[x]--;
                    }
                    cnt[x]--;
                    k++;
                }
            }
        }
        printf("%d\n",q.size()-use);//输出队列中信息的数量减去已经阅读过的信息的数量
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值