先把所有已经确定的在列表前面登陆的人员数量算出。然后通过这些人数计算后面的是否可行。
在已知的连续列表总最多出现一个可能的领导人,然后加上没有在列表中出现的即可。
分类讨论即可
#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;
struct DATA
{
int op, id;
} dt[100005];
int ans[100005], bb[100005];
bool vis[100005], go[100005];
int main()
{
int sum, n, m, i, j, id;
scanf("%d%d",&n,&m);
memset(vis,0,sizeof(vis));
memset(go,0,sizeof(go));
memset(bb,0,sizeof(bb));
char op[4];
for(i=1;i<=m;i++){
scanf("%s%d",op,&id);
bb[id]=1;
dt[i].id=id;
if(op[0]=='+'){
dt[i].op=0;
}else {
dt[i].op=1;
}
}
sum=0;
for(i=1;i<=m;i++){
if(dt[i].op==1){
if(!go[dt[i].id]){
sum++;
}
}
go[dt[i].id]=1;
}
memset(go,0,sizeof(go));
int curid=-1;
bool in=0;
for(i=1;i<=m;i++){
if(dt[i].op==0){
if(i==1){
if(sum==0){
curid=dt[i].id;
in=1;
}
}else{
if(curid==dt[i].id) in=1;
if(curid!=dt[i].id&&!in){
curid=-1;
}
}
sum++;
}else{
sum--;
if(curid==dt[i].id&&sum==0){
in=0;
}else if(!go[dt[i].id]&&sum==0){
curid=dt[i].id;
in=0;
}else if(curid!=dt[i].id){
}else{
curid=-1;
}
}
go[dt[i].id]=1;
}
int k=0;
if(curid!=-1) ans[k++]=curid;
for(i=1;i<=n;i++){
if(!bb[i]) ans[k++]=i;
}
sort(ans,ans+k);
printf("%d\n",k);
for(i=0;i<k;i++)
printf("%d ",ans[i]);
puts("");
return 0;
}