题意:

解:

发现我们每次染的都是不同的颜色,那么用lct维护的话一个颜色就会在一个splay里。染色是access。

维护每个节点到根路径上的虚边数量。

虚边的切换只会在access和link中出现。于是access的时候顺便修改那个子树。lct上啥也不用维护。

查询链可以用两端点减去lca。

 #include <bits/stdc++.h>

 const int N = , INF = 0x3f3f3f3f;

 struct Edge {
int nex, v;
}edge[N << ]; int tp; int e[N], n, siz[N], pos[N], id[N], d[N], num, top[N], father[N], son[N]; /// tree
int fa[N], s[N][], stk[N], Top; /// lct
bool rev[N];
int large[N << ], tag[N << ]; /// seg inline void add(int x, int y) {
tp++;
edge[tp].v = y;
edge[tp].nex = e[x];
e[x] = tp;
return;
} void DFS_1(int x, int f) { /// father siz son d
siz[x] = ;
fa[x] = father[x] = f;
for(int i = e[x]; i; i = edge[i].nex) {
int y = edge[i].v;
if(y == f) continue;
d[y] = d[x] + ;
DFS_1(y, x);
siz[x] += siz[y];
if(siz[y] > siz[son[x]]) {
son[x] = y;
}
}
return;
} void DFS_2(int x, int f) { /// top id pos
top[x] = f;
pos[x] = ++num;
id[num] = x;
if(son[x]) DFS_2(son[x], f);
for(int i = e[x]; i; i = edge[i].nex) {
int y = edge[i].v;
if(y == father[x] || y == son[x]) continue;
DFS_2(y, y);
}
return;
} inline void Pushdown(int o) {
if(tag[o]) {
int ls = o << , rs = o << | ;
tag[ls] += tag[o];
tag[rs] += tag[o];
large[ls] += tag[o];
large[rs] += tag[o];
tag[o] = ;
}
return;
} void build(int l, int r, int o) {
if(l == r) {
large[o] = d[id[r]];
return;
}
int mid = (l + r) >> ;
build(l, mid, o << );
build(mid + , r, o << | );
large[o] = std::max(large[o << ], large[o << | ]);
return;
} void add(int L, int R, int v, int l, int r, int o) {
if(L <= l && r <= R) {
large[o] += v;
tag[o] += v;
return;
}
Pushdown(o);
int mid = (l + r) >> ;
if(L <= mid) add(L, R, v, l, mid, o << );
if(mid < R) add(L, R, v, mid + , r, o << | );
large[o] = std::max(large[o << ], large[o << | ]);
return;
} int getMax(int L, int R, int l, int r, int o) {
if(L <= l && r <= R) return large[o];
int mid = (l + r) >> , ans = -INF;
Pushdown(o);
if(L <= mid) ans = std::max(ans, getMax(L, R, l, mid, o << ));
if(mid < R) ans = std::max(ans, getMax(L, R, mid + , r, o << | ));
return ans;
} int ask(int p, int l, int r, int o) {
if(l == r) return large[o];
Pushdown(o);
int mid = (l + r) >> ;
if(p <= mid) return ask(p, l, mid, o << );
else return ask(p, mid + , r, o << | );
} inline void pushdown(int x) {
if(rev[x]) {
std::swap(s[x][], s[x][]);
if(s[x][]) rev[s[x][]] ^= ;
if(s[x][]) rev[s[x][]] ^= ;
rev[x] = ;
}
return;
} inline void pushup(int x) {
return;
} inline bool no_root(int x) {
return (s[fa[x]][] == x) || (s[fa[x]][] == x);
} inline void rotate(int x) {
int y = fa[x];
int z = fa[y];
bool f = (s[y][] == x); fa[x] = z;
if(no_root(y)) {
s[z][s[z][] == y] = x;
}
s[y][f] = s[x][!f];
if(s[x][!f]) {
fa[s[x][!f]] = y;
}
s[x][!f] = y;
fa[y] = x; pushup(y);
return;
} inline void splay(int x) {
int y = x;
stk[++Top] = y;
while(no_root(y)) {
y = fa[y];
stk[++Top] = y;
}
while(Top) {
pushdown(stk[Top]);
Top--;
} y = fa[x];
int z = fa[y];
while(no_root(x)) {
if(no_root(y)) {
(s[z][] == y) ^ (s[y][] == x) ?
rotate(x) : rotate(y);
}
rotate(x);
y = fa[x];
z = fa[y];
}
pushup(x);
return;
} inline void change(int x, int v) {
pushdown(x);
while(s[x][]) {
x = s[x][];
pushdown(x);
}
/// x
add(pos[x], pos[x] + siz[x] - , v, , n, );
return;
} inline void access(int x) {
int y = ;
while(x) {
splay(x);
if(s[x][]) change(s[x][], );
if(y) change(y, -);
s[x][] = y;
pushup(x);
y = x;
x = fa[x];
}
return;
} inline int lca(int x, int y) {
while(top[x] != top[y]) {
if(d[top[x]] < d[top[y]]) {
y = father[top[y]];
}
else {
x = father[top[x]];
}
}
return d[x] < d[y] ? x : y;
} inline int ask(int x, int y) {
//printf("ask : %d %d lca %d \n", x, y, lca(x, y));
//printf("ask : %d + %d - 2 * %d \n", ask(pos[x], 1, n, 1), ask(pos[y], 1, n, 1), ask(pos[lca(x, y)], 1, n, 1));
return ask(pos[x], , n, ) + ask(pos[y], , n, ) - * ask(pos[lca(x, y)], , n, );
} inline int query(int x) {
return getMax(pos[x], pos[x] + siz[x] - , , n, );
} int main() {
int m;
scanf("%d%d", &n, &m);
for(int i = , x, y; i < n; i++) {
scanf("%d%d", &x, &y);
add(x, y); add(y, x);
}
/// init
DFS_1(, );
DFS_2(, );
build(, n, ); for(int i = , f, x, y; i <= m; i++) {
scanf("%d%d", &f, &x);
if(f == ) { /// change
access(x);
}
else if(f == ) {
scanf("%d", &y);
printf("%d\n", ask(x, y) + );
}
else { /// f == 3
printf("%d\n", query(x) + );
}
}
return ;
}

AC代码

洛谷P3703 树点涂色的更多相关文章

  1. P3703 [SDOI2017]树点涂色

    P3703 [SDOI2017]树点涂色 链接 分析: 首先对于询问,感觉是线段树维护dfs序,每个点记录到根的颜色个数.第二问差分,第三问区间取max. 那么考虑修改,每次将一个点的颜色变成和父节点 ...

  2. 【LG3703】[SDOI2017]树点涂色

    [LG3703][SDOI2017]树点涂色 题面 洛谷 题解 更博辣,更博辣!!! 猪年的第一篇博客 一次只能染根到\(x\),且染的颜色未出现过 这句话是我们解题的关键. 设\(x\)到根的颜色数 ...

  3. [Sdoi2017]树点涂色 [lct 线段树]

    [Sdoi2017]树点涂色 题意:一棵有根树,支持x到根染成新颜色,求x到y颜色数,求x子树里点到根颜色数最大值 考场发现这个信息是可减的,但是没想到lct 特意设计成lct的形式! 如何求颜色数? ...

  4. 「SDOI2017」树点涂色 解题报告

    「SDOI2017」树点涂色 我sb的不行了 其实一开始有一个类似动态dp的想法 每个点维护到lct树上到最浅点的颜色段数,然后维护一个\(mx_{0,1}\)也就是是否用虚儿子的最大颜色 用个set ...

  5. 【BZOJ4817】树点涂色(LCT,线段树,树链剖分)

    [BZOJ4817]树点涂色(LCT,线段树,树链剖分) 题面 BZOJ Description Bob有一棵n个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义 ...

  6. [BZOJ4817][SDOI2017]树点涂色(LCT+DFS序线段树)

    4817: [Sdoi2017]树点涂色 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 692  Solved: 408[Submit][Status ...

  7. 【BZOJ4817】【SDOI2017】树点涂色 [LCT][线段树]

    树点涂色 Time Limit: 10 Sec  Memory Limit: 128 MB[Submit][Status][Discuss] Description Bob有一棵n个点的有根树,其中1 ...

  8. 【BZOJ4817】[Sdoi2017]树点涂色 LCT+线段树

    [BZOJ4817][Sdoi2017]树点涂色 Description Bob有一棵n个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义一条路径的权值是:这条路 ...

  9. [Bzoj4817] [Sdoi2017]树点涂色 (LCT神题)

    4817: [Sdoi2017]树点涂色 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 629  Solved: 371[Submit][Status ...

随机推荐

  1. vue的地图插件amap

    https://www.jianshu.com/p/0011996b81e2(amap) npm install vue-amap --save

  2. Java 线程的创建和启动

    Java 使用 Thread 类代表线程,所有的线程对象都必须是 Thread 类或其子类的实例.每个线程的作用是完成一定的任务,实际上就是执行一段程序流(一段顺序执行的代码). Java 使用线程执 ...

  3. Hbase 架构体系

    有2个节点进程,一个是master,另一是regionserver.

  4. kprobe原理解析

    参考  http://www.cnblogs.com/honpey/p/4575928.html kprobe是linux内核的一个重要特性,是一个轻量级的内核调试工具,同时它又是其他一些更高级的内核 ...

  5. C# 中那些常用的工具类(Utility Class)(三)

    今天来接着写这个系列的文章,这一篇主要是用来介绍关于C#中的XML序列化的问题,这个相信大家一定会经常使用它,特别是在WPF中,有时候我们需要将我们后台的数据保存在数据库中,从而在软件下一次启动的时候 ...

  6. React Native & debug & debugger

    React Native & debug & debugger http://localhost:8081/debugger-ui/ react-devtools # yarn: $ ...

  7. python3高级编程

    1. SMTP发送邮件 internet相关协议: http:网页访问相关,httplib,urllib,xmlrpclib ftp:文件传输相关, ftplib, urllib nntp:新闻和帖子 ...

  8. linode上切换Linux到FreeBSD

    PS:不是真正的无缝切换,数据需要自己备份.还原. Linode官方给出了一篇文章:https://www.linode.com/docs/tools-reference/custom-kernels ...

  9. poj2112(网络流-最大流+二分)

    题意:给你k个挤奶器,c头牛,每个挤奶器能放m头牛,问你奶牛需要走的最大距离最小是多少: 解题思路:因为最大距离最小,也就是求最小的距离满足所有牛都能到,所以我们先用floyd跑最短路,把所有点之间的 ...

  10. 洛谷P1622释放囚犯

    题目: 这个题很明显是一个区间DP,但是比较不同的是,这个题它很像区间DP的经典题——石子合并. 然后我傻傻的搞了这个题搞了一下午,然后几乎看遍了全网的题解,就只看懂了这个方法,可能是我太菜了吧,但是 ...