BZOJ 2243 樹鏈剖分

2022-08-31 03:42:08 字數 2720 閱讀 9413

題意:中文題目

思路:樹鏈剖分。首先考慮求區間顏色段數的問題, 我們可以用線段樹維護:區間左右端點(st,ed),區間顏色段數(val),懶惰標記(lazy:是否整個區間被染成同一種顏色),區間左右端點的顏色(lcolor,rcolor),然後在查詢的時候如果當前區間的左子樹的右端點的顏色等於右子樹的左端點的顏色,那麼查詢答案要減一。由於樹鏈剖分在查詢時是有可能兩端的分鏈一起向上爬的。所以我們在查詢時需要記錄兩端上一次查詢結果的deep小的那個點的顏色。如果當前查詢的鏈和上一次查詢的交接處位置顏色一致那麼答案就要減一。 

注意: 顏色可能為0

#define _crt_secure_no_deprecate#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

using

namespace

std;

#define l(x) x<<1

#define r(x) x<<1|1typedef

long

long

intll;

const

int inf = 0x3f3f3f3f

;const ll inf =0x3f3f3f3f3f3f3f3fll;

const

int maxn = 1e5 + 10

;int

head[maxn], tot, cnt,value[maxn];

struct

edgeedges[maxn * 2

];void add(int u, int

v)int

id[maxn], son[maxn], deep[maxn], size[maxn], fa[maxn], reid[maxn], top[maxn];

void

init()

void dfs1(int u, int p,int

dep)}}

}void dfs2(int u, int

tp) dfs2(son[u], tp);

for (int i = head[u]; i != -1; i =edges[i].next)

}}struct

nodeseg[maxn * 4

];void pushup(intk)}

void pushdown(intk)}

void build(int l, int r, int

k)

int mid = (l + r) / 2

; build(l, mid, l(k)); build(mid + 1

, r, r(k));

pushup(k);

}void modify(int l,int r,int val,int

k) pushdown(k);

if (r <=seg[l(k)].ed)

else

if (l >=seg[r(k)].st)

else

pushup(k);

}void modify(int u, int v,int

val)

modify(id[f1], id[u], val,1);

u = fa[f1]; f1 =top[u];

}if (deep[u] >deep[v])

modify(id[u], id[v],val, 1);

}node query(

int l, int r, int

k) node ans;

pushdown(k);

if (r <=seg[l(k)].ed)

else

if (l >=seg[r(k)].st)

else

}pushup(k);

return

ans;

}int query(int u, int

v) node temp = query(id[f1], id[u], 1

); ans += temp.val - (lrc ==temp.rcolor);

u = fa[f1]; f1 = top[u]; lrc =temp.lcolor;

}if (deep[u] >deep[v])

node temp = query(id[u], id[v], 1

); ans += temp.val - (temp.rcolor == rlc) - (temp.lcolor ==lrc);

return

ans;

}int

main()

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

dfs1(

1, 1, 0); dfs2(1, 1); build(1, n, 1

);

while (m--)}}

//#ifdef local_time

//cout << "[finished in " << clock() - start << " ms]" << endl;

//#endif

return0;

}

樹鏈剖分 bzoj2243

time limit 20 sec memory limit 512 mb submit 2492 solved 960 submit status 給定一棵有n個節點的無根樹和m個操作,操作有2類 1 將節點a到節點b路徑上所有點都染成顏色c 2 詢問節點a到節點b路徑上的顏色段數量 連續相同顏色...

bzoj 2243 染色 樹鏈剖分

首先這是個挺裸的題,由於太久沒寫剖分導致調了好久,前天調了一下午,一直查不到錯 昨晚在看春晚的時候突然靈機一動,發現合併的時候出了問題,開電腦把它a掉了 感覺自己也蠻拼的給定 一棵有n 個節點的 無根樹和 m個操作 操作有 2類 1 將節點a 到節點b 路徑上所 有點都染 成顏色c 2 詢問節點a ...

bzoj 2243 樹鏈剖分 染色

time limit 20 sec memory limit 512 mb submit 3205 solved 1238 submit status discuss 給定一棵有n個節點的無根樹和m個操作,操作有2類 1 將節點a到節點b路徑上所有點都染成顏色c 2 詢問節點a到節點b路徑上的顏色段...