Qtree3題解(樹鏈剖分 線段樹 set)

2022-05-07 19:03:10 字數 2106 閱讀 3924

外話:最近洛谷加了好多好題啊...原題入口 這題好像是spoj的題,挺不錯的。看沒有題解還是來一篇...

很易懂吧。。

我的做法十分的暴力:樹鏈剖分(偽)+線段樹+std :: set...

首先,我們可以考慮每次修改乙個點的顏色的影響。

易知,翻轉乙個點顏色,只會對於他的子樹產生影響,對於別的點就毫無意義了。

然後,只要學過一點樹鏈剖分的就知道,我們可以將整棵樹按它的\(dfs\)序進行標號,

每個點的序號就是\(dfn\),

然後記下它的子樹大小\(size\),然後對於每個點\(u\)所在的子樹區間就是\([dfn[u], dfn[u]+size[u]-1]\)。

所以每次操作的時候,只要對於那一段區間進行修改就行了。

然後我們要修改和查詢什麼呢?不就是查詢包含這個點,且深度最小的黑點嗎?(需要把\(1\)作為根)

所以,我們每次記下乙個區間中,包含這個點的所有黑色標號以及他們的深度,用\(pair\)記錄一下(因為這個可以

自動按照第一關鍵字排序),再用\(set\)維護一下區間最值就行了。

每次更新的時候只要在\(set\)裡面\(insert\)和\(erase\)。

查詢就是從根節點一直向下跑,不斷取乙個深度更小的\(ans\)。

具體有些實現在程式中會體現的……

總時間複雜度\(o(q \log \ n \log q)\) 空間複雜度也是\(o(q \log \ n \log \ q)\)。(所以說很暴力嘛……)

#include #define for(i, l, r) for(int i = (l), _end_ = (int)(r); i <= _end_; ++i)

#define fordown(i, r, l) for(int i = (r), _end_ = (int)(l); i >= _end_; --i)

#define set(a, v) memset(a, v, sizeof(a))

using namespace std;

bool chkmin(int &a, int b)

bool chkmax(int &a, int b)

inline int read()

void file()

const int n = 1e5 + 1e3, m = n << 1;

int n, q;

int sz[n], dfn[n], dep[n];

int to[m], next[m], head[n], e = 0;

void add(int u, int v)

void dfs(int u, int fa)

}//就是樹鏈剖分的第乙個dfs,求出size,dep,dfn

typedef pairpii;

#define mp make_pair

#define lson o << 1, l, mid

#define rson o << 1 | 1, mid + 1, r

sets[n << 2];

bool col[n];//因為不知道是變啥顏色,所以要記一下原來的顏色

bool uopt; int ul, ur; pii uv;

void update(int o, int l, int r)

int mid = (l + r) >> 1;

if (ul <= mid) update(lson);

if (ur > mid) update(rson);

}pii ans; int up;

void query(int o, int l, int r)

const int inf = 0x3f3f3f3f;

int main ()

dfs(1, 0);

for (i, 1, q) else

}//cerr << clock() << endl;

return 0;

}

後記:看到很多dalao都是用啥 主席樹,倍增,和不用\(set\)的線段樹做過去的。跑得都比我快,希望後面有人能講一講qaq。

LCA 樹鏈剖分 線段樹

給出乙個 n 個節點的有根樹 編號為 0 到 n 1 根節點為 0 乙個點的深度定義為這個節點到根的距離 1 設 dep i 表示點 i 的深度,lca i,j 表示 i 與 j 的最近公共祖先。有 q 次詢問,每次詢問給出 l,r,z 求 dep lca i,z 即,求在 l,r 區間內的每個節點...

樹鏈剖分 咕咕咕了好久好久的qtree3

顯然qtree系列都是樹鏈剖分辣 發現自己沒有專門整理過樹鏈剖分耶 辣麼就把這篇部落格魔改成樹鏈剖分好辣 貌似除了樹剖也沒什麼好寫的 廢話了辣麼多終於開始了 一.樹剖怎麼寫鴨 二.樹剖有什麼用鴨 三.qtree3題解 樹剖,顧名思義就是把樹 剖成一條一條的東西,然後把一棵樹搞成乙個序列。咋剖?對於樹...

QTREE 子杰樹 線段樹 樹鏈剖分

題解 樹鏈剖分的模板題,我早就寫過了,但長時間沒做樹剖的題目,這個模板已經忘得差不多了,今天再做用來複習樹剖,順便卡卡常數。include include include include include include includeusing namespace std define file r...