樹上操作 相遇

2021-09-10 01:58:49 字數 1250 閱讀 3150

傳送門

神仙部落格!!

大概題意就是給定m條路徑,求第i條和前面i-1條中的多少個相交。

當路徑a與其他路徑相交,分兩種情況:其他路徑的lca在a上,或者a的lca在其他路徑上。

(以下先不考慮兩條路徑的lca重合的情況)

(以下子樹可以轉化為dfs序的乙個區間)

第一種情況:在路徑兩個端點上打乙個+1的標記,在lca上打乙個-2的標記,統計路徑a的子樹和,就可以得到多少路徑穿過了路徑a。因為沒有穿過a的路徑的貢獻就是    -2+1+1=0    ,穿過a了的話貢獻就是1。就相當於乙個單點修改,區間查詢。

第二種情況:可以轉化為求乙個點到根的路徑上有多少個lca。那麼對於乙個路徑的lca(設為g),g的子樹(包含g)的貢獻都要加1。因為g的子樹到根結點都要穿過g。相當於乙個區間修改,單點查詢。可以用樹狀陣列差分。

最後可以單獨用乙個陣列記錄lca重合的情況。

**:

#include#define lowbit(x) (x&(-x))

using namespace std;

const int maxn=2e5+10;

int n,m,u,v,g;

int head[maxn],next[maxn<<1],v[maxn<<1],cnt=0;

int f[maxn][20],dep[maxn],l[maxn],r[maxn],tot=0;

int tr1[maxn],tr2[maxn],on[maxn];

inline void change1(int x,int v)

inline void change2(int x,int v)

inline int sum1(int x)

inline int sum2(int x)

inline void add(int u,int v)

inline int read()

void dfs(int u,int fa)

inline void pre()

inline int getans(int u,int v,int g)

inline void print(int x)

int main()

}

bzoj4034 樹上操作

有一棵點數為 n 的樹,以點 1 為根,且樹點有邊權。然後有 m 個 操作,分為三種 操作 1 把某個節點 x 的點權增加 a 操作 2 把某個節點 x 為根的子樹中所有點的點權都增加 a 操作 3 詢問某個節點 x 到根的路徑中所有點的點權和。第一行包含兩個整數 n,m 表示點數和運算元。接下來一...

HAOI2015 樹上操作

題目描述 有一棵點數為 n 的樹,以點 1 為根,且樹點有邊權。然後有 m 個操作,分為三種 操作 1 把某個節點 x 的點權增加 a 操作 2 把某個節點 x 為根的子樹中所有點的點權都增加 a 操作 3 詢問某個節點 x 到根的路徑中所有點的點權和。輸入格式 第一行包含兩個整數 n,m 表示點數...

洛谷 3178 樹上操作

作為乙個比樹剖板子還板子的題目,它竟讓我卡了近乙個下午。出去不敢說自己是學過樹剖的人。對於這道題目,會樹剖的都會做 不會別說會樹剖 其主要任務是用樹剖維護區間和,支援區間 單點修改。我的 這次主要就是卡在這裡了。首先我們要明確每個變數陣列的意義,並且明確他們下表的意義。int siz 102020 ...