題意:中文題目
思路:樹鏈剖分。首先考慮求區間顏色段數的問題, 我們可以用線段樹維護:區間左右端點(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路徑上的顏色段...