社区讨论
Only AC on HACK 0pts 求助,码风良好,玄双关
P2486[SDOI2011] 染色参与者 1已保存回复 0
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @mk8f370w
- 此快照首次捕获于
- 2026/01/10 22:45 上个月
- 此快照最后确认于
- 2026/01/14 15:30 上个月
CPP
#include <cstdio>
#include <vector>
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
const int MAXSZ = 1 << 20;
char ch, buf[MAXSZ], *p1, *p2;
#define ge() (p1 == p2 && (p2 = buf + fread(p1 = buf, 1, MAXSZ, stdin), p1 == p2) ? EOF : *p1++)
#define end() putchar('\n')
#define space() putchar(' ')
#define mset(a, b) memset(a, b, sizeof a)
template <typename T_T>
inline void read(T_T &x) {
x = 0;
bool flag = false;
while (ch < '0' || '9' < ch) ch = ge(), flag |= (ch == '-');
while ('0' <= ch && ch <= '9') {
x = x * 10 + (ch ^ 48);
ch = ge();
}
x = flag ? -x : x;
}
inline void cread(char &x) {
while (ch != 'Q' && ch != 'C') ch = ge();
x = ch;
}
template <typename T_T>
inline void write(T_T x) {
if (x < 0) {
putchar('-');
x = -x;
}
if (x > 9) write(x / 10);
putchar(x % 10 | 48);
}
template <typename T_T>
inline T_T min(T_T x, T_T y) { return x < y ? x : y; }
template <typename T_T>
inline T_T max(T_T x, T_T y) { return x > y ? x : y; }
const int N = 1e5 + 5, Root = 1;
int opl, opr, opval;
std::vector <int> tr[N];
int n, T, initial[N], first[N], dfn[N], pdfn, fa[N], depth[N], sz[N], sheavy[N], heavy[N], Rc, Lc;
struct SGT {
SGT *son[2];
int chead, ctail, ans, lazy;
}*null, *root;
void newNode(SGT *&u) {u = new SGT; *u = {{null, null}, -1, -1, 0, -1};}
void CalcLazy(SGT *u, int val) {
if (val == -1) return ;
if (u == null) return ;
u -> ans = 1, u -> chead = val, u -> ctail = val;
u -> lazy = val;
}
void PushDown(SGT *u) {
CalcLazy(u -> son[0], u -> lazy);
CalcLazy(u -> son[1], u -> lazy);
u -> lazy = -1;
}
void PushUp(SGT *u) {
if (u -> son[0] == null || u -> son[1] == null) return ;
u -> chead = u -> son[0] -> chead;
u -> ctail = u -> son[1] -> ctail;
u -> ans = u -> son[0] -> ans + u -> son[1] -> ans;
if (u -> son[0] -> ctail == u -> son[1] -> chead) -- u -> ans;
}
void modify(SGT *&u, int l, int r) {
// printf("Modify ---> target:[%d,%d] Now:[%d,%d] Val:[%d,%d]\n", opl, opr, l, r, u -> chead, u -> ctail);
if (opl <= l && r <= opr) {CalcLazy(u, opval); return ;}
PushDown(u);
int mid = l + r >> 1;
if (opl <= mid) modify(u -> son[0], l, mid);
if (mid < opr) modify(u -> son[1], mid + 1, r);
PushUp(u);
}
int query(SGT *&u, int l, int r) {
// printf("Query --> target:[%d,%d] Now:[%d,%d] Val:[%d,%d,%d]\n", opl, opr, l, r, u -> chead, u -> ctail, u -> ans);
if (l == opl) Lc = u -> chead;
if (r == opr) Rc = u -> ctail;
if (opl <= l && r <= opr) return u -> ans;
PushDown(u);
int mid = l + r >> 1;
int res = 0;
if (opr <= mid) res = query(u -> son[0], l, mid);
else if (mid < opl) res = query(u -> son[1], mid + 1, r);
else {
res = query(u -> son[0], l, mid) + query(u -> son[1], mid + 1, r);
if (u -> son[0] -> ctail == u -> son[1] -> chead) -- res;
}
PushUp(u);
return res;
}
// void Print(SGT *now, int l, int r) {
// if (now == null) return ;
// PushDown(now);
// int mid = l + r >> 1;
// Print(now -> son[0], l, mid);
// Print(now -> son[1], mid + 1, r);
// PushUp(now);
// printf("section:[%d,%d] head:%d tail:%d Ans:%d\n", l, r, now -> chead, now -> ctail, now -> ans);
// }
void dfs1(int u) {
sz[u] = 0;
depth[u] = depth[fa[u]] + 1;
for (auto v : tr[u]) {
if (v == fa[u]) continue ;
fa[v] = u;
dfs1(v);
sz[u] += sz[v];
if (sz[v] > sz[heavy[u]])
heavy[u] = v;
}
++ sz[u];
}
void dfs2(int u) {
dfn[u] = ++ pdfn;
if (heavy[u]) {
first[heavy[u]] = first[u];
dfs2(heavy[u]);
}
// printf("%d %d %d\n", u, first[u], heavy[u]);
sheavy[u] = sheavy[heavy[u]] + 1;
for (auto v : tr[u]) {
if (v == fa[u] || v == heavy[u]) continue ;
first[v] = v;
dfs2(v);
}
}
void FindPath(int u, int v, int type) {
if (type == 1) read(opval);
int clast1 = -1, clast2 = -1, ans = 0;
for (; first[u] != first[v]; u = fa[first[u]]) {
if (depth[first[u]] < depth[first[v]]) std::swap(u, v), std::swap(clast1, clast2);
opl = dfn[first[u]], opr = dfn[u];
if (type == 2) {
ans += query(root, 1, n);
if (clast1 == Lc) -- ans;
clast1 = Rc;
}
else modify(root, 1, n);
}
if (depth[u] > depth[v]) std::swap(u, v), std::swap(clast1, clast2);
opl = dfn[u], opr = dfn[v];
if (type == 2) {
ans += query(root, 1, n);
if (clast1 == Rc) -- ans;
if (clast2 == Lc) -- ans;
write(ans);
}
else modify(root, 1, n);
}
void build(SGT *&u, int l, int r) {
newNode(u);
if (l == r) return ;
int mid = l + r >> 1;
build(u -> son[0], l, mid);
build(u -> son[1], mid + 1, r);
PushUp(u);
}
int main() {
// freopen("Ryan.in", "r", stdin);
// freopen("Ryan.out", "w", stdout);
null = new SGT;
*null = {{null, null}, -1, -1, 0, -1};
root = null;
read(n), read(T); build(root, 1, n);
for (int i = 1; i <= n; i++) read(initial[i]);
for (int i = 1; i < n; i++) {
int u, v; read(u), read(v);
tr[u].emplace_back(v);
tr[v].emplace_back(u);
}
dfs1(Root);
first[Root] = Root;
dfs2(Root);
for (int i = 1; i <= n; i++) {
opl = dfn[i], opr = dfn[i]; opval = initial[i];
modify(root, 1, n);
}
// for (int i = 1; i <= n; i++)
// printf("%d %d\n", dfn[i], initial[i]);
// Print(root, 1, n);
while (T --) {
char ch; cread(ch);
int u, v; read(u), read(v);
// Print(root, 1, n), end();
if (ch == 'Q') FindPath(u, v, 2), end();
else FindPath(u, v, 1);
}
// fclose(stdin), fclose(stdout);
return 0;
}
回复
共 0 条回复,欢迎继续交流。
正在加载回复...