CF 421C Online Meeting

Nearly each project of the F company has a whole team of developers working on it. They often are in different rooms of the office in different cities and even countries. To keep in touch and track the results of the project, the F company conducts shared online meetings in a Spyke chat.

One day the director of the F company got hold of the records of a part of an online meeting of one successful team. The director watched the record and wanted to talk to the team leader. But how can he tell who the leader is? The director logically supposed that the leader is the person who is present at any conversation during a chat meeting. In other words, if at some moment of time at least one person is present on the meeting, then the leader is present on the meeting.

You are the assistant director. Given the 'user logged on'/'user logged off' messages of the meeting in the chronological order, help the director determine who can be the leader. Note that the director has the record of only a continuous part of the meeting (probably, it's not the whole meeting).

Input

The first line contains integers n and m (1 ≤ n, m ≤ 105) — the number of team participants and the number of messages. Each of the next m lines contains a message in the format:

  • 'id': the record means that the person with number id (1 ≤ id ≤ n) has logged on to the meeting.
  • 'id': the record means that the person with number id (1 ≤ id ≤ n) has logged off from the meeting.

Assume that all the people of the team are numbered from 1 to n and the messages are given in the chronological order. It is guaranteed that the given sequence is the correct record of a continuous part of the meeting. It is guaranteed that no two log on/log off events occurred simultaneously.

Output

In the first line print integer k (0 ≤ k ≤ n) — how many people can be leaders. In the next line, print k integers in the increasing order — the numbers of the people who can be leaders.

If the data is such that no member of the team can be a leader, print a single number 0.

Sample test(s)
input
5 4
+ 1
+ 2
- 2
- 1
output
4
1 3 4 5 
input
3 2
+ 1
- 2
output
1
3 
input
2 4
+ 1
- 1
+ 2
- 2
output
0
input
5 6
+ 1
- 1
- 3
+ 3
+ 4
- 4
output
3
2 3 5 
input
2 4
+ 1
- 2
+ 2
- 1
output
0
题意:给出会议(可能不是整个会议)的出入情况,求可能全程在场的人
思路:如果是I的进操作,如果有记录中没有进操作而出操作在后面,则I不是领导人。如果前面有进的人还没出也不行。如果这个不是第一个操作且前一个操作不是I的出操作也不行。
     如果是出操作,如果场中有剩余人则不行(包括进了没出和记录中没进但出在后面)。如果后面还有操作且不是I的进操作也不行。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
#include <vector>
#include <cmath>
#include <set>
#include <map>
using namespace std;
#define inf 0x3f3f3f3f
#define LL long long int
#define min(a,b) a>b?b:a;
#define max(a,b) a>b?a:b;
#define lson id<<1,l,mid
#define rson id<<1|1,mid+1,r
#define maxn 100080
bool vis[maxn];
int val[maxn];
int jin[maxn];
struct Item
{
	char ope[2];
	int x;
}item[maxn];
vector <int> ans;
int main()
{
	//freopen("in.txt","r",stdin);
	int n,m;
	while(scanf("%d%d",&n,&m)==2)
	{
		ans.clear();
		memset(vis,0,sizeof(vis));
		memset(val,0,sizeof(val));
		int weijinxianchu = 0;
		jin[0] = 0;
		for(int i = 1;i <= m;i++)
		{
			scanf("%s%d",item[i].ope,&item[i].x);
			if(!val[item[i].x] && item[i].ope[0] == '-')
			{
				weijinxianchu = max(weijinxianchu,i);
			}
			if(item[i].ope[0] == '+')	jin[i] = jin[i-1]+1;
			else if(val[item[i].x])	jin[i] = jin[i-1]-1;
			else jin[i] = jin[i-1];
			if(!val[item[i].x]) val[item[i].x] = i;
		}
		for(int i = 1;i <= m;i++)
		{
			if(item[i].ope[0] == '+')
			{
				if(weijinxianchu > i)	vis[item[i].x] = 1;//未进就出在后
				if(i != 1 && !(item[i-1].ope[0] == '-' &&item[i-1].x == item[i].x))
					vis[item[i].x] = 1;
				if(jin[i-1] > 0)	vis[item[i].x] = 1;
			}
			else 
			{
				if(weijinxianchu > i)	vis[item[i].x] = 1;
				if((val[item[i].x] == i && jin[i-1] >= 1) || jin[i-1] > 1)	vis[item[i].x] = 1;
				if(i != m && !(item[i+1].ope[0] == '+' && item[i+1].x == item[i].x))
					vis[item[i].x] = 1;
			}
		}
		
		for(int i = 1;i <= n;i++)
		{
			if(!vis[i])	ans.push_back(i);
		}
		printf("%d\n",ans.size());
		int len = ans.size();
		for(int i = 0;i < len;i++)
		{
			printf("%d",ans[i]);
			if(i == len-1)	printf("\n");
			else printf(" ");
		}
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值