1. 程式人生 > >4419. [SHOI2013]發微博【亂搞】

4419. [SHOI2013]發微博【亂搞】

一個 app 才會 計算 AR pos 之間 現在 break

Description

剛開通的SH微博共有n個用戶(1..n標號),在短短一個月的時間內,用戶們活動頻繁,共有m條按時間順序的記錄: ! x 表示用戶x發了一條微博; + x y 表示用戶x和用戶y成為了好友 - x y 表示用戶x和用戶y解除了好友關系 當一個用戶發微博的時候,所有他的好友(直接關系)都會看到他的消息。 假設最開始所有人之間都不是好友關系,記錄也都是合法的(即+ x y時x和y一定不是好友,而- x y時x和y一定是好友)。 問這m條記錄發生之後,每個用戶分別看到了多少條消息。

Input

第1行2個整數n,m。 接下來m行,按時間順序讀入m條記錄,每條記錄的格式如題目所述,用空格隔開。

Output

輸出一行n個用空格隔開的數(行末無空格),第i個數表示用戶i最後看到了幾條消息。

Sample Input

2 8
! 1
! 2
+ 1 2
! 1
! 2
- 1 2
! 1
! 2

Sample Output

1 1
只有第4和第5條記錄對應的消息被看到過。其他消息發送時,1和2不是好友。

對100%的數據,N<=200000,M<=500000

感覺現在做數據結構做傻了……一看到類似操作就往數據結構上艹
後來發現唯一能搞的lct好像還搞不了emmm……
然後又想著能不能離線搞,發現+x y -x y 只有他們之間的一段才會有貢獻

每個點單獨開一個set,計算和其相連的人
當為嘆號的時候cnt++
那麽我們就在加的時候把當前cnt減掉,然後在後面減的時候再加上新的cnt,
這一段區間內的貢獻就都被考慮進去了
最後再遍歷一遍set把過程中沒有減掉的貢獻算上就行了

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<set>
 4 #define N (200005)
 5 using namespace std;
 6 set<int>s[N];
 7 set<int>::iterator po;
8 int n,m,x,y,cnt[N],ans[N]; 9 char opt[2]; 10 int main() 11 { 12 scanf("%d%d",&n,&m); 13 for (int i=1; i<=m; ++i) 14 { 15 scanf("%s",opt); 16 switch (opt[0]) 17 { 18 case !: 19 { 20 scanf("%d",&x); 21 cnt[x]++; 22 break; 23 } 24 case +: 25 { 26 scanf("%d%d",&x,&y); 27 s[y].insert(x); 28 s[x].insert(y); 29 ans[x]-=cnt[y]; 30 ans[y]-=cnt[x]; 31 break; 32 } 33 case -: 34 { 35 scanf("%d%d",&x,&y); 36 s[y].erase(s[y].find(x)); 37 s[x].erase(s[x].find(y)); 38 ans[x]+=cnt[y]; 39 ans[y]+=cnt[x]; 40 break; 41 } 42 } 43 } 44 for (int i=1; i<=n; i++) 45 for (po=s[i].begin(); po!=s[i].end(); ++po) 46 ans[*po]+=cnt[i]; 47 for (int i=1; i<=n-1; ++i) 48 printf("%d ",ans[i]); 49 printf("%d",ans[n]); 50 }

4419. [SHOI2013]發微博【亂搞】