1. 程式人生 > 實用技巧 >洛谷 P3998 [SHOI2013]發微博

洛谷 P3998 [SHOI2013]發微博

題目連結:https://www.luogu.com.cn/problem/P3998

題目描述

剛開通的 SH 微博共有n個使用者(1n標號),在這短短一個月的時間內,使用者們活動頻繁,共有m條按時間順序的記錄:

! x 表示使用者 x 發了一條微博;
+ x y 表示使用者 x 和使用者 y 成為了好友
− x y 表示使用者 x 和使用者 y 解除了好友關係

當一個使用者發微博的時候,所有他的好友(直接關係)都會看到他的訊息。

假設最開始所有人之間都不是好友關係,記錄也都是合法的(即+ x yx和y一定不是好友,而− x yx和y一定是好友)。

問這m條記錄發生之後,每個使用者分別看到了多少條訊息。

輸入格式

1行兩個整數n,m。

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

輸出格式

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

說明/提示

對於100%的資料,n200000,m500000

思想

離線思想,記錄操作倒序處理。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=500010;
 4 int n,m,mem[maxn][2],ans[maxn],cnt[maxn];
 5 char opt[maxn];
 6 int main(){
7 scanf("%d%d",&n,&m); 8 for(int i=1;i<=m;i++){ 9 cin>>opt[i]; 10 scanf("%d",&mem[i][0]); 11 if(opt[i]!='!') 12 scanf("%d",&mem[i][1]); 13 } 14 for(int i=m;i>=1;i--){ 15 if(opt[i]=='!') 16 ++cnt[mem[i][0
]]; 17 if(opt[i]=='+'){ 18 ans[mem[i][0]]+=cnt[mem[i][1]]; 19 ans[mem[i][1]]+=cnt[mem[i][0]]; 20 } 21 if(opt[i]=='-'){ 22 ans[mem[i][0]]-=cnt[mem[i][1]]; 23 ans[mem[i][1]]-=cnt[mem[i][0]]; 24 } 25 } 26 for(int i=1;i<=n;i++) 27 printf("%d ",ans[i]); 28 return 0; 29 }