[SHOI 2013] 发微博

[题目链接]

        https://www.lydsy.com/JudgeOnline/problem.php?id=4419

[算法]

        用std :: set维护每个人的好友集合

        当两人成为好友时将每人接收到的消息减去另一个人之前发的消息 , 当两人解除好友时 , 将每人接受到的消息加上另一个人发的消息 , 这是一个类似于差分前缀和的过程 , 不再赘述 , 详见代码

        时间复杂度 : O(MlogN)

[代码]

        

#include<bits/stdc++.h>
using namespace std;
#define MAXN 500010

int n , m;
int cnt[MAXN] , ans[MAXN];
set< int > S[MAXN];

int main()
{
    
    scanf("%d%d" , &n , &m);
    for (int i = 1; i <= m; i++)
    {
        char op[5];
        scanf("%s" , &op);
        if (op[0] == '!')
        {
            int x;
            scanf("%d" , &x);
            cnt[x]++;    
        } else if (op[0] == '+')
        {
            int x , y;
            scanf("%d%d" , &x , &y);
            S[x].insert(y);
            S[y].insert(x);
            ans[x] -= cnt[y];
            ans[y] -= cnt[x];
        } else
        {
            int x , y;
            scanf("%d%d" , &x , &y);
            ans[x] += cnt[y];
            ans[y] += cnt[x];
            S[x].erase(S[x].find(y));
            S[y].erase(S[y].find(x));
        }
    }
    for (int i = 1; i <= n; i++)
    {
        for (set< int > :: iterator it = S[i].begin(); it != S[i].end(); it++)
            ans[i] += cnt[*it];
    }
    for (int i = 1; i < n; i++) printf("%d " , ans[i]);
    printf("%d
" , ans[n]);
    
    return 0;
}
原文地址:https://www.cnblogs.com/evenbao/p/9909897.html