Codeforces #366 Div. 2 C. Thor (模拟

 

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

 

模拟题 : 设的方法采用一个 r 数组(第几个app已经阅读过的消息的数量),和app数组(第几个app发出的消息的总数),加上一个 q 队列。

 

思路:

查询==1的时候,入队(记录顺序), sum++ (sum 为全部的剩余 没阅读的数量)

查询==2的时候,针对一个app,sum -(这个app发出的消息的总数 - 这个app已经阅读过的消息的数量),然后用 app数组 更新 r 数组,表示这个app的全部的消息都已经被阅读过了。

查询==3的时候,采用 q.front 和 q.pop() 的方法一个一个出队,t 为要阅读 队列前面 t 个数量的消息,但是因为有出队的过程,所以出队的数量要用cnt记录,t= t - cnt 。 按顺序出队,当 某一个app消息的数量 > 这个app已经读过的消息的数量(即这个app存在还没被读过的消息),sum就减去 “没被读过的消息的数量”,更新 r 数组。

 

#include<iostream>
#include<cstdio>
#include <cctype>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<string>
#include<cmath>
#include<set>
#include<vector>
#include<stack>
#include<queue>
#include<map>
using namespace std;
#define ll long long
#define mem(a,x) memset(a,x,sizeof(a))
#define se second    
#define fi first
const int INF= 0x3f3f3f3f;
const int N=3e5+5;

int n,m,x,t,c,cnt=0;
ll sum=0;  //查询的答案 
int r[N],app[N]; //读过的 和 总的 
int num[N]={0};
queue<int>q;

int main()
{
    cin>>n>>m;
    while(m--)
    {
        scanf("%d",&c);
        if(c==1)
        {
            scanf("%d",&x);
            
            sum++;
            q.push(x); //存第几种app
            app[x]++;
        }
        if(c==2)
        {
            scanf("%d",&x);
            
            sum-= app[x]-r[x];
            r[x]=app[x];
        }
        if(c==3)
        {
            scanf("%d",&t);
            
            t-=cnt; //要减去 已经出队的数量 (题目要求可以阅读重复的信息) 
            while(!q.empty()&&t>0)
            {
                int f=q.front();
                q.pop();
                cnt++;//出队数量 
                num[f]++;
                if(num[f]>r[f])
                {
                    sum-=num[f]-r[f];
                    r[f]=num[f];
                }
                t--;
            }
        }
        cout<<sum<<endl;
    }
}

 

posted @ 2018-08-16 11:07  木流牛马  阅读(119)  评论(0编辑  收藏  举报