雙重祖先(DFS序的應用)

2021-09-19 07:36:59 字數 2488 閱讀 1292

dfs序 可以讓我們在   線性的陣列內 處理樹上的子樹等問題

所以我們只需要給第乙個樹 建立dfs序,然後用線段樹(或者樹狀陣列)維護一下就好了

第一棵樹的dfs序

第二顆樹

直接查詢 節點 3  的祖先 裡 哪些 也是第一棵樹的祖先

用線段樹

1.對兩個 1 節點區間 內所有數 + 1

2.對兩個 2 節點區間 內所有樹 + 1

3.查詢乙個3節點,被覆蓋幾次(res) ,ans += res;

4.兩個節點3 的區間 所有數 + 1

(節點3沒有子節點)

5.兩個節點3 的區間內  所有數 - 1

過程類似如上

然後最後輸出ans就行了

樹狀陣列(每次更新乙個節點 的【左端點】到【maxn】都+1,【右端點+1】到【maxn】都-1,查乙個節點就行)

#include #include #include #include #include #include #include #include #include #include #include #include #define clear( x , y ) memset( x , y , sizeof(x) );

#define qcin() std::ios::sync_with_stdio(false);

using namespace std;

typedef long long ll;

const int maxn = 1e6 + 7;

const int inf = 1e9 + 7;

int cnt;

ll a[maxn];

struct nodefind[maxn];

vector c[maxn];

vector g[maxn];

ll n , m;

ll ans;

struct edgetree[maxn];

void pushup( ll x )

void build( ll l , ll r , ll x )

ll mid = ( l + r ) / 2;

build( l , mid , x * 2 );

build( mid + 1 , r , x * 2 + 1 );

pushup( x );

}void pushdown( ll x )

void update_line( ll l , ll r , ll add , ll x )

pushdown( x );

ll mid = ( tree[x].l + tree[x].r ) / 2;

if( l <= mid ) update_line( l , r , add , x * 2 );

if( r > mid ) update_line( l , r , add , x * 2 + 1 );

pushup( x );

}ll query( ll l , ll r , ll x )

pushdown( x );

ll mid = ( tree[x].l + tree[x].r ) / 2;

ll res = 0ll;

if( l <= mid ) res += query( l , r , x * 2 );

if( r > mid ) res += query( l , r , x * 2 + 1 );

return res;

}void getdfslist(int x,int fa)

//a[++cnt] = (ll)x;

cnt++;

find[x].r = (ll)cnt;

}void scanner()

for(int i=1 ; i < n ; i++)

}void init()

void gdfs(int x , int fa)

update_line(find[x].l , find[x].r , -1 , 1);

}void opt()

printf("\n");

for(int i = 1 ; i <= n ; i++)

}int main()

dfs序及其應用

dfs序是用來處理子樹一類問題的,可以把子樹問題轉化為區間問題,以便借助線段樹或樹狀陣列處理。根據dfs的順序來給節點編號,在進入這個節點時更新in陣列,出去的時候更新out陣列,這樣以i為根的子樹的操作就可以變成區間 in i out i 的操作了。int in 100005 out 100005...

雙重map函式的應用

夏天來了好開心啊,呵呵,好多好多水果 joe經營著乙個不大的水果店.他認為生存之道就是經營最受顧客歡迎的水果.現在他想要乙份水果銷售情況的明細表,這樣joe就可以很容易掌握所有水果的銷售情況了.input 第一行正整數n 0每組測試資料的第一行是乙個整數m 0兩組測試資料之間有乙個空行.最後一組測試...

DFS序與尤拉序的區別

dfs序 是指將一棵樹被dfs時所經過的節點順序 不繞回原點 尤拉序 就是從根結點出發,按dfs的順序在繞回原點所經過所有點的順序。通過dfs序判斷v節點的時間區間是否在u節點的時間區間內。通過尤拉序求u和v的最近公共祖先。dfs序 a b d e g c f h 尤拉序 a b d d e g g...