Codechef EDGEST 線段樹合併

2021-08-20 05:49:34 字數 1773 閱讀 4937

給定相同點集上的兩棵生成樹 t1 和 t2,節點編號為 1 ∼ n。對於 t1 中的每條邊 e1,你需要

求在 t2 中有多少條邊 e2 滿足:

t1 − e1 + e2(從 t1 中刪去 e1 再加上 e2 構成的圖)是一棵生成樹;

t2 − e2 + e1 也是一棵生成樹。

2 ≤ n ≤ 2*10^5

不難發現如果兩條邊可以互相替代,則必須要滿足e2在t2中e1兩端點的路徑上,反過來也要滿足。

那麼我們先把t2的每條邊在t1上差分一下,就是在兩端點處插入,然後在lca處刪除,那麼限制條件就被去掉了乙個。

把邊下放到點,現在我們要實現的單點修改,和支援鏈上權值查詢。

可以用樹鏈剖分做到倆log,也可以直接維護入棧出棧序做到乙個log。然後把線段樹自底向上合併就好了。

複雜度o(n

logn

) o(n

logn

)。

#include

#include

#include

#include

#include

#include

const int n=200005;

int n,tot,sz,in[n],out[n],rt[n],ans[n];

struct treet[n*60];

std::vector vec[n];

intread()

while (ch>='0'&&ch<='9')

return

x*f;

}struct tree

e[n*2];

void addedge(int u,int v)

void dfs1(int

x)

}void dfs2(int

x,int chain)

void dfs3(int

x)

int get_lca(int

x,int

y)

return dep[x]y]?x:y;

}}t1,t2;

int newnode()

int merge(int

x,int

y)void modify(int &d,int l,int r,int

x,int

y)int query(int d,int l,int r,int

x,int

y)void solve(int

x) for (int i=0;iif (x==1) return;

int lca=t1.get_lca(x,t2.fa[x]);

ans[x]=query(rt[x],1,tot,1,in[x])+query(rt[x],1,tot,1,in[t2.fa[x]])-2

*query(rt[x],1,tot,1,in[lca]);

}void clear()

int main()

for (int i=1;iint

x=read(),y=read();

t1.addedge(x,y);

}t1.dfs1(1);t1.dfs2(1,1);t1.dfs3(1);

t2.dfs1(1);t2.dfs2(1,1);

for (int i=1;i*2-1;i+=2)

solve(1);

for (int i=1;i*2-1;i+=2)

puts("");

}return

0;}

對於線線問題

以下是乙個大佬的總結 authorlcy註明出處,摘自 1 n條直線最多分平面問題 題目大致如 n條直線,最多可以把平面分為多少個區域。析 可能你以前就見過這題目,這充其量是一道初中的思考題。但乙個型別的題目還是從簡單的入手,才容易發現規律。當有n 1條直線時,平面最多被分成了f n 1 個區域。則...

交叉線和直通線

2010 1 24 21 25 49 問 copper cross over與copper straight through兩種電纜有什麼區別?這兩種銅質電纜,我就是搞不懂有什麼不同!還有serial dte和serial dce兩種線的區別又是什麼呢?這兩種線與題目上的兩種線的接頭是不是一樣的呢?...

OC OD 線或線與邏輯

一.什麼是oc od 集電極開路門 集電極開路 oc或源極開路od open drain是漏極開路輸出的意思,相當於集電極開路 open collector 輸出,即ttl中的集電極開路 oc 輸出。一般用於線或 線與,也有的用於電流驅動。open drain是對mos管而言,open collec...