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