卧薪尝胆,厚积薄发。
SHOI2013 发微博
Date: Mon Sep 17 14:28:00 CST 2018
In Category:
NoCategory
Description:
$n$
个人,
$m$
个操作,每次操作为
$a$
发了一条微博,
$a$
和
$b$
成为好友,
$a$
和
$b$
解除好友,直接好友可以看见对方的微博,问最后每个人看见了多少别人的微博。
$1\le n\le 200000$
Solution:
发现并不能用什么数据结构来维护,
$LCT$
也不能修改整棵树信息,一种解法是每个人用一个
$set<pair<int,int>>$
来维护所有和他是好友的人,
$pair$
的第一个元素是好友的编号,第二个元素是建立好友时
$a$
发的微博个数,在解除好友时用这时
$a$
发的微博个数减去建立时的就是这段时间对答案的贡献,最后再把到最后都是好友的统计一遍。
Code:
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<set>
#include<cstring>
using namespace std;
inline char getc()
{
register char c = getchar();
while(c != '!' && c != '+' && c != '-')c = getchar();
return c;
}
inline int read()
{
register int res = 0;
register char c = getchar();
while(!isdigit(c))c = getchar();
while(isdigit(c))
{
res = (res << 1) + (res << 3) + c - '0';
c = getchar();
}
return res;
}
int n,m;
#define MAXN 200010
set< pair<int,int> > s[MAXN];
int cnt[MAXN];
int ans[MAXN];
int main()
{
scanf("%d%d",&n,&m);
char c;
int a,b;
for(int i = 1;i <= m;++i)
{
c = getc();
if(c == '!')
{
a = read();
++cnt[a];
}
if(c == '+')
{
a = read();b = read();
s[a].insert(make_pair(b,cnt[a]));
s[b].insert(make_pair(a,cnt[b]));
}
if(c == '-')
{
a = read();b = read();
set< pair<int,int> >::iterator it;
it = s[a].lower_bound(make_pair(b,0));
ans[b] += cnt[a] - it -> second;
s[a].erase(it);
it = s[b].lower_bound(make_pair(a,0));
ans[a] += cnt[b] - it -> second;
s[b].erase(it);
}
}
for(int i = 1;i <= n;++i)
{
for(set< pair<int,int> >::iterator it = s[i].begin();it != s[i].end();++it)
{
ans[it -> first] += cnt[i] - it -> second;
}
}
for(int i = 1;i <= n;++i)
{
cout << ans[i] << " ";
}
cout << endl;
return 0;
}
In tag:
Copyright © 2020
wjh15101051
ღゝ◡╹)ノ♡