我們的CPU遭到攻擊 LOJ558

2022-05-27 11:21:17 字數 2961 閱讀 2543

給你乙個有 \(n\) 個點的森林,點有黑白兩種顏色,初始時所有點都是白色,森林的每條邊有邊權,初始時這個森林有 \(m\) 條邊。

對這個森林進行 \(k\) 次操作,操作有三種:

第一行三個非負整數,分別表示 \(n,m,k\)。

以下 \(m\) 行,每行三個整數 \(u,v,w\),表示初始時有一條邊連線 \(u\) 和 \(v\),長度為 \(w\)。

以下 \(k\) 行,每行描述乙個操作,格式如上所述。

對於每個 q 操作,單獨一行輸出乙個整數表示答案。

保證任何時候這個圖都是乙個森林。

lct維護子樹資訊

假設現在需要用lct維護原樹中乙個子樹的 \(siz\)

為了方便查詢,一般會把原樹中一條重鏈的頂端 \(x\) 的子樹資訊儲存在(\(x\) 在lct中所在的二叉樹的根)的位置

如上圖,原樹中的 \(siz[1]\) 實際上存在lct中的 \(siz[3]\) 裡,而 \(siz[1]\) 裡存的其實是 \(1\) 和 \(2\) 的權值和

但是乙個點子樹的 \(siz\) 不僅包含自己所在的那條重鏈啊 如何維護輕子樹的大小?

很簡單,我們記 \(lsiz[x]\) 表示lct中 \(x\) 的所有輕子樹的 \(siz\) 之和,這樣 \(siz[x]\) 就等於 \(siz[lson]+siz[rson]+lsiz[x]+1\)

如何維護 \(lsiz\) 呢?首先,在link(x,y)操作時 \(y\) 會變成 \(x\) 的乙個新的輕兒子,所以 \(lsiz[x]\) 要加上 \(siz[y]\)

其次,access時經過的點的重兒子變成了輕兒子,而某個輕兒子變成了重兒子,要注意更新 \(lsiz\)

總之記住輕兒子發生變化的時候記得更新 \(lsiz\) 即可

但是實際應用中我們肯定不會用lct去維護子樹 \(siz\) 這種這麼簡單的東西的(好像還真有,而且不少),所以來看看這道題

對於詢問操作,其實我們可以通過lct來做乙個makeroot(u)的操作,這樣每次詢問就變成了詢問所有黑點到根的距離之和了

對於每條邊 \(u,v\),新建乙個點 \(w\),把 \(w\) 的點權設為邊權,把 \(u,v\) 的點權設為 \(0\),然後在lct中連 \(u,w\) 和 \(w,v\),這樣詢問路徑長度就變成詢問路徑上的點權和了

對於點 \(x\) 如何統計答案?

這裡是一張lct的部分圖,圖中的箭頭表示某乙個點走到根應該沿什麼方向走

由於lct中左子樹的點在原樹中深度較小,所以應該向左走

我們設 \(sum[x]\) 表示lct中 \(x\) 子樹的點權和,\(siz[x]\) 表示有多少個黑點,\(lsiz[x]\) 表示 \(x\) 的所有輕子樹中共有多少個黑點

不難發現,如果圖中所有點想要從 \(x\) 開始走到 \(x\) 所在重鏈的頂端,那麼需要走過的路徑長度是 \(sum[lson]+val[x]\)

有多少個點要走過去呢?\(lsiz[x]+siz[rson]\) 個,如果 \(x\) 也是黑點就還要額外+1

所以這裡 \(x\) 的答案就是 \((sum[lson]+val[x])*(lsiz[x]+siz[rson]+color[x])\)

累加答案也可以用類似的方法 即\(ans[x]=ans[lson]+ans[rson]+lightans[x]\);\(lightans[x]\) 就是輕子樹的答案之和

然後是一些細節:

進行access時,某個重兒子變成了輕兒子,而輕兒子變成了重兒子,所以要記得更新 \(lsiz[x]\) 之類的東西

注意,執行makeroot操作時翻轉了整棵lct,所以我們不僅要記錄從右子樹向左子樹走的答案,還要記錄從左到右的答案,這樣才能 \(o(1)\) 翻轉

時間複雜度 \(o(n\log n)\)

**還算較為好寫

#include #define n 1000005 

using namespace std;

typedef long long ll;

templateinline void read(t &num)

templateinline void write(t num)

int n, tot, m, q, ch[n][2], fa[n];

ll siz[n], lsiz[n], tp[n], sum[n], val[n], lans[n], rans[n], light[n], tag[n];

inline void pushup(int x)

inline void rev(int x)

inline bool isroot(int x)

inline void pushdown(int x)

inline void rotate(int x)

int stk[n], top;

inline void splay(int x)

rotate(x);

} }inline void access(int x)

}inline void makeroot(int x)

inline void link(int x, int y)

inline void cut(int x, int y)

map, int> mp;

int main()

char s[5];

for (int i = 1, x, y; i <= q; i++) else if (s[0] == 'c') else if (s[0] == 'f') else

} return 0;

}

如何保障IIS的安全避免伺服器遭到攻擊

因此,現在採用iis作為web伺服器軟體的單位還是很多的。預設情況下,這些伺服器必須允許公眾訪問其資源。但我們發現,許多單位在防禦攻擊上的時間花費甚至遠遠多於維護和提供web服務的時間。不過,這裡的攻擊靜悄悄。除非你單位的web站點成為毀滅性攻擊的受害者,或者受到某種惡意 的注入,一般來說,黑客會以...

L8 CPU管理的直觀想法

設好pc初值就完事,cpu會自動地順著位址下移,不斷取指執行。當遇到io操作之類的,cpu會處於等待狀態 時間很長 等著fprintf fp,d sum 執行完,才會繼續執行下去。遇到等待時,就切換到其他程式繼續執行,等待原程式列印成功,就切換回去,繼續執行原程式。就好比,自己燒水的過程 往水壺裡面...

OS 李治軍 L8 CPU管理的想法

作業系統核心 管理硬體 管理cpu 引出多程序影象 作業系統核心影象 自動取指令執行,給個位址,從記憶體中取出指令執行,並且是自動向下執行。看一眼菜譜,做一步工作。設定好pc初值就可以了,剩下cpu會往下工作。管理cpu 設定pc的初值 有乙個問題 有io指令的速度遠遠小於存計算指令,io特別慢。如...