#倒推#洛谷 3998 [SHOI2013]發微博
阿新 • • 發佈:2020-08-18
分析
考慮\(x\)看到\(y\)的訊息條數等於互刪時\(y\)發的訊息條數減去互加時\(y\)發的訊息條數
為了讓最後\(x\)和\(y\)不再為好友,那可以將操作反過來,因為一開始他們一定不是好友,
所以記錄某人發的訊息條數\(cnt\),倒序維護髮微博,
加好友(\(ans_x+=cnt_y,ans_y+=cnt_x\)),
刪好友(\(ans_x-=cnt_y,ans_y-=cnt_x\))即可
程式碼
#include <cstdio> #include <cctype> #define rr register using namespace std; const int N=500011; int opt[N],X[N],Y[N],ans[N>>1],cnt[N>>1],n,m; inline signed iut(){ rr int ans=0; rr char c=getchar(); while (!isdigit(c)) c=getchar(); while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar(); return ans; } inline void print(int ans){ if (ans>9) print(ans/10); putchar(ans%10+48); } signed main(){ n=iut(); m=iut(); for (rr int i=1;i<=m;++i){ rr char c=getchar(); while (c!='!'&&c!='+'&&c!='-') c=getchar(); opt[i]=(c=='!')+(c=='+')*2+(c=='-')*3,X[i]=iut(); if (opt[i]>1) Y[i]=iut(); } for (rr int i=m;i;--i){ if (opt[i]==1) ++cnt[X[i]]; else if (opt[i]==2) ans[X[i]]+=cnt[Y[i]],ans[Y[i]]+=cnt[X[i]]; else ans[X[i]]-=cnt[Y[i]],ans[Y[i]]-=cnt[X[i]]; } for (rr int i=1;i<=n;++i) print(ans[i]),putchar(32); return 0; }