【BZOJ4419】[Shoi2013]发微博【set】

记录每个人发的消息总数,用set记录每个人当前的朋友。


对于x和y,y对x的贡献为:

x和y为朋友时y发的消息数 = x和y解除好友时y发的消息数 - x和y刚刚成为朋友时y发的消息数。


最后再把最终朋友的贡献加上就好啦。


/* Footprints In The Blood Soaked Snow */
#include <cstdio>
#include <set>

using namespace std;

typedef set<int>::iterator siit;

const int maxn = 200005;

int n, m, cnt[maxn], ans[maxn];
set<int> fri[maxn];

inline int iread() {
	int f = 1, x = 0; char ch = getchar();
	for(; ch < '0' || ch > '9'; ch = getchar()) f = ch == '-' ? -1 : 1;
	for(; ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';
	return f * x;
}

int main() {
	n = iread(); m = iread();
	while(m--) {
		char ch = getchar(); for(; ch != '!' && ch != '+' && ch != '-'; ch = getchar());
		if(ch == '!') cnt[iread()]++;
		else if(ch == '+') {
			int x = iread(), y = iread();
			ans[x] -= cnt[y]; ans[y] -= cnt[x];
			fri[x].insert(y); fri[y].insert(x);
		}
		else if(ch == '-') {
			int x = iread(), y = iread();
			ans[x] += cnt[y]; ans[y] += cnt[x];
			fri[x].erase(y); fri[y].erase(x);
		}
	}
	for(int i = 1; i <= n; i++) for(siit it = fri[i].begin(); it != fri[i].end(); it++)
		ans[i] += cnt[*it];

	for(int i = 1; i < n; i++) printf("%d ", ans[i]); printf("%d\n", ans[n]);
	return 0;
}



你可能感兴趣的:(【BZOJ4419】[Shoi2013]发微博【set】)