大概就是加好友则双方互加到对方的set里,加之前减去对方set的tag;删好友从对方set删去,加上对方set的tag。(根据差分的的思想)进出一次队列得到的正分数减去负分数恰是其得分。
千万注意最后一定要弹出set中所有元素(不知道sb地WA了多少次。。。)
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<set>
#include<algorithm>
using namespace std;
const int maxn=200005;
int n,m;
int ans[maxn],bucket[maxn];
set<int>s[maxn];
int main()
{
scanf("%d%d",&n,&m);
char op[2];
while(m--)
{
scanf("%s",op);
if(op[0]=='!')
{
int a;
scanf("%d",&a);
bucket[a]++;
}
else if(op[0]=='+')
{
int a,b;
scanf("%d%d",&a,&b);
ans[a]-=bucket[b];
ans[b]-=bucket[a];
s[a].insert(b);
s[b].insert(a);
}
else
{
int a,b;
scanf("%d%d",&a,&b);
ans[a]+=bucket[b];
ans[b]+=bucket[a];
s[a].erase(b);
s[b].erase(a);
}
}
for(int i=1;i<=n;i++)
for(set<int>::iterator it=s[i].begin();it!=s[i].end();it++)
ans[*it]+=bucket[i];
for(int i=1;i<n;i++)
printf("%d ",ans[i]);
printf("%d",ans[n]);
return 0;
}