給定相同點集上的兩棵生成樹 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...