題目描述:給出一棵有n個節點的帶邊權的有根樹,然後有q次操作,維護兩個功能:
1.修改:將點u,v的路徑上的邊邊權統一加w
2.查詢:詢問以i號節點為根的子樹的點的兩兩之間路徑和,輸出對2018取模的結果
20%資料,n,q<=200;
40%資料n,q<=5000;
100%資料,n,q<=50000;
20%做法:
對於每個修改,我們可以暴力改,但是對於每個詢問我們不能列舉兩個點再暴力跑路徑,考慮在求路徑的方法上進行優化,那麼應該怎麼做呢:不妨設點u,v的lca是點i,那麼我們可以用乙個神奇的方法求u,v的路徑和:對於每乙個節點維護乙個值,就是從它到根節點的路徑和,如圖。
求節點6到節點9的路徑可以這麼求:先求出節點6,9的lca,發現他們的lca是3,然後取出節點9,節點5到根節點的路徑和,分為12和14,把他們加起來,發現值剛剛好是它們的路徑和加上它們的lca到根節點路徑的兩倍,所以再減去lca到路徑和的兩倍就好了。這樣,時間複雜度是3次方級別的,如果寫的是倍增lca則再乘個log。
40%做法:
我們換一種思路,能不能不列舉點對呢?答案是可以的,我們考慮對於i的子樹,某一條邊的單獨貢獻:
如圖,我們考慮紅色這條邊的貢獻 ,我們發現,如果點對中的兩個點都是子樹u內的節點,那麼這條邊是不會對那個點對產生影響的,同理,如果點對中的兩個點都是在子樹u的外面,這條邊依然不會產生影響,那麼對於一條邊,它有且只有對那些點對中:乙個點在u的子樹內,乙個點在u的子樹外的情況產生影響,假設u的子樹大小為size【u】,i的子樹大小為size【i】,那麼在u的子樹中選點的方案數是size【u】種,在u的子樹外選點的方案數是(size【i】-size【u】)種,那麼讓u子樹內的點和子樹外的點兩兩配對,一共有size【u】*(size【i】-size【u】)種方案,那麼這條邊的貢獻就是,這條邊的權值val乘上size【u】*(size【i】-size【u】)這樣我們先dfs一遍,求出以每個點為根時的子樹的大小,修改邊的時候依然暴力改,求邊的時候對每條邊像上面那樣單獨考慮貢獻,就可以過40%的資料了,時間複雜度:
100%做法:
首先我們意識到不能直接暴力改邊,由於是鏈上的修改,我們很容易想到樹剖,那麼,我們應該用資料結構維護一些什麼資訊才能讓計算答案,變得更簡便呢:考慮如果每次詢問都是詢問1號節點,那麼節點u連向父親的邊的貢獻就是val*size【u】*(n-size【u】)而如果詢問的是i號節點,那麼貢獻是val*size【u】*(i-size【u】)=val*size【u】*(n-size【u】)-(n-size【i】)*val*size【u】,而val*size【u】*(n-size【u】)和val*size【u】兩個值都是和詢問的i節點無關的,所以我們只需要維護這兩個值,假設sum1=val*size【u】*(n-size【u】),sum2=val*size【u】,那麼這條邊對i的子樹的貢獻就是sum1-(n-size【i】)*sum2。這樣,這道題就完美的解決了,時間複雜度:
佛山市選2013 海明距離
description 對於二進位制串a,b,他們之間的海明距離是指兩個串異或之後串中1的個數。異或的規則為 0 xor 0 0 1 xor 0 1 0 xor 1 1 1 xor 1 0 計算兩個串之間的海明距離的時候,他們的長度必須相同。現在我們給出n個不同的二進位制串,請計算出這些串兩兩之間的...
佛山市選2015 石子遊戲
alice 和 bob 總喜歡聚在一起玩遊戲 t t 今天他 她 們玩的是一款新型的取石子遊戲。遊戲一開始有n堆石子,alice 和 bob 輪流取出石子。在每次操作中,遊戲者必須選擇其中的一堆石子,並作出下列的其中一種操作 1 移去整堆石子 2 假設石子堆中有x顆石子,取出y顆石子,其中1 y 遊...
3230 佛山市選2013 樹環轉換
給定一棵n個節點的樹,去掉這棵樹的一條邊需要消耗值1,為這個圖的兩個點加上一條邊也需要消耗值1。樹的節點編號從1開始。在這個問題中,你需要使用最小的消耗值 加邊和刪邊操作 將這棵樹轉化為環,不允許有重邊。環的定義如下 1 該圖有n個點,n條邊。2 每個頂點的度數為2。3 任意兩點是可達的。樹的定義如...