there

#include <iostream>
#include <cstdio>
using namespace std;
int n, m, dfn[100005], idx, hea[100005], cnt, uu, vv, siz[100005], fa[100005][19];
int dep[100005], val[400005], dui[100005], opt, ch[100005][2], tag[400005];
int af[100005];
struct Edge{
int too, nxt;
}edge[200005];
void add_edge(int fro, int too){
edge[++cnt].nxt = hea[fro];
edge[cnt].too = too;
hea[fro] = cnt;
}
bool isRoot(int x){
return ch[af[x]][0]!=x && ch[af[x]][1]!=x;
}
bool getW(int x){
return ch[af[x]][1]==x;
}
void dfs(int x, int f){
fa[x][0] = f;
af[x] = f;
dep[x] = dep[f] + 1;
dfn[x] = ++idx;
dui[idx] = dep[x];
siz[x] = 1;
for(int i=1; i<=16; i++)
fa[x][i] = fa[fa[x][i-1]][i-1];
for(int i=hea[x]; i; i=edge[i].nxt){
int t=edge[i].too;
if(t!=f){
dfs(t, x);
siz[x] += siz[t];
}
}
}
void build(int o, int l, int r){
if(l==r) val[o] = dui[l];
else{
int mid=(l+r)>>1;
int lson=o<<1;
int rson=lson|1;
if(l<=mid) build(lson, l, mid);
if(mid<r) build(rson, mid+1, r);
val[o] = max(val[lson], val[rson]);
}
}
void rotate(int x){
int old=af[x], oldf=af[old], w=getW(x);
if(!isRoot(old)) ch[oldf][ch[oldf][1]==old] = x;
ch[old][w] = ch[x][w^1]; ch[x][w^1] = old;
af[ch[old][w]] = old; af[ch[x][w^1]] = x; af[x] = oldf;
}
void splay(int x){
while(!isRoot(x)){
int f=af[x];
if(!isRoot(f)) rotate(getW(f)==getW(x)?f:x);
rotate(x);
}
}
int findRoot2(int x){
while(ch[x][0]) x = ch[x][0];
return x;
}
void sgtPushDown(int o, int l, int r, int lson, int rson, int mid){
val[lson] += tag[o];
val[rson] += tag[o];
tag[lson] += tag[o];
tag[rson] += tag[o];
tag[o] = 0;
}
void update(int o, int l, int r, int x, int y, int k){
if(l>=x && r<=y){
val[o] += k;
tag[o] += k;
}
else{
int mid=(l+r)>>1;
int lson=o<<1;
int rson=lson|1;
if(tag[o]) sgtPushDown(o, l, r, lson, rson, mid);
if(x<=mid) update(lson, l, mid, x, y, k);
if(mid<y) update(rson, mid+1, r, x, y, k);
val[o] = max(val[lson], val[rson]);
}
}
void access(int x){
int y=0;
while(x){
splay(x);
if(ch[x][1]){
int t=findRoot2(ch[x][1]);
update(1, 1, n, dfn[t], dfn[t]+siz[t]-1, 1);
}
ch[x][1] = y;
if(ch[x][1]){
int t=findRoot2(ch[x][1]);
update(1, 1, n, dfn[t], dfn[t]+siz[t]-1, -1);
}
y = x;
x = af[x];
}
}
int getLca(int u, int v){
if(dep[u]<dep[v]) swap(u, v);
for(int i=16; i>=0; i--)
if(dep[fa[u][i]]>=dep[v])
u = fa[u][i];
if(u==v) return u;
for(int i=16; i>=0; i--)
if(fa[u][i]!=fa[v][i]){
u = fa[u][i];
v = fa[v][i];
}
return fa[u][0];
}
int query(int o, int l, int r, int x, int y){
if(l>=x && r<=y) return val[o];
else{
int mid=(l+r)>>1;
int lson=o<<1;
int rson=lson|1;
int ans=0;
if(tag[o]) sgtPushDown(o, l, r, lson, rson, mid);
if(x<=mid) ans = max(ans, query(lson, l, mid, x, y));
if(mid<y) ans = max(ans, query(rson, mid+1, r, x, y));
return ans;
}
}
int main(){
cin>>n>>m;
for(int i=1; i<n; i++){
scanf("%d %d", &uu, &vv);
add_edge(uu, vv);
add_edge(vv, uu);
}
dfs(1, 0);
build(1, 1, n);
while(m--){
scanf("%d", &opt);
if(opt==1){
scanf("%d", &uu);
access(uu);
}
else if(opt==2){
scanf("%d %d", &uu, &vv);
int lca=getLca(uu, vv);
printf("%d\n", query(1, 1, n, dfn[uu], dfn[uu])+query(1, 1, n, dfn[vv], dfn[vv])-2*query(1, 1, n, dfn[lca], dfn[lca])+1);
}
else{
scanf("%d", &uu);
printf("%d\n", query(1, 1, n, dfn[uu], dfn[uu]+siz[uu]-1));
}
}
return 0;
}

loj2001 「SDOI2017」树点涂色的更多相关文章

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

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

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

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

  3. [SDOI2017][bzoj4817] 树点涂色 [LCT+线段树]

    题面 传送门 思路 $LCT$ 我们发现,这个1操作,好像非常像$LCT$里面的$Access$啊~ 那么我们尝试把$Access$操作魔改成本题中的涂色 我们令$LCT$中的每一个$splay$链代 ...

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

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

  5. P3703 [SDOI2017]树点涂色

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

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

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

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

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

  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. linux配置tomcat已service方式启动

    1. 在/etc/init.d目录下新建文件,命名为tomcat2. 对tomcat文件进行编辑,执行 # cd /etc/init.d/ # vi tomcat 将下面代码粘上去 注意:下面代码ja ...

  2. ionic 2 起航 控件的使用 客户列表场景(四)

    接下来,我们的客户列表要怎么刷新数据呢? 我们不会安卓开发,不会ios开发,没关系,我们还有ionic 2.ionic 2的控件 Ion-refresher 轻松帮我们搞掂. <!--下拉刷新- ...

  3. iPad开发简单介绍

    iPad开发最大的不同在于iPhone的就是屏幕控件的适配,以及横竖屏的旋转. Storyboard中得SizeClass的横竖屏配置,也不支持iPad开发. 1.在控制器中得到设备的旋转方向 在 i ...

  4. shell脚本安装nginx

    #!/bin/bash N_url="http://nginx.org/download/nginx-1.8.0.tar.gz" N_pack=`echo $N_url|awk - ...

  5. HTTP 错误 404.15 - Not Found请求筛选模块被配置为拒绝包含的查询字符串过长的请求

    web项目中,get方式传值是通过地址栏中的url参数进行传递的.除了浏览器对url长度的限制大小不一之外,出于安全考虑, IIS中对于URL中参数大小也是有限制的,默认为2048KB. 如果参数大于 ...

  6. 交叉熵cross entropy和相对熵(kl散度)

    交叉熵可在神经网络(机器学习)中作为损失函数,p表示真实标记的分布,q则为训练后的模型的预测标记分布,交叉熵损失函数可以衡量真实分布p与当前训练得到的概率分布q有多么大的差异. 相对熵(relativ ...

  7. QT5:第一章 初始化

    一.简介 二.新建项目 在项目Application中: QT Widgets Application(桌面QT应用) QT Console Application(控制台QT应用) QT for P ...

  8. SVN:The working copy is locked due to a previous error (二)

    之前也碰到过这种问题,但是根本问题不同,解决方案不同. 传送门:SVN:The working copy is locked due to a previous error (二) 本次错误如图: 解 ...

  9. NSOperation、NSOperationQueue

    NSOperation.NSOperationQueue NSOperation 和 NSOperationQueue 配合使用也能实现多线程. NSOperation 继承于 NSObject,是一 ...

  10. const,static,extern,#define

    一.const // 简单定义变量,可以修改变量的值 ; a = ; // const的用法 // 用法一: ; ; // 不允许修改,因为 const 修饰 b/c,指定 b/c 为常量!! // ...