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. Mysql有什么办法批量去掉某个字段字符中的空格

    Mysql有什么办法批量去掉某个字段字符中的空格?不仅是字符串前后的空格,还包含字符串中间的空格,答案是 replace,使用mysql自带的 replace 函数,另外还有个 trim 函数.   ...

  2. 密码强度的正则表达式(JavaScript)总结

    简言 本文给出了两个密码强度的正则表达式方案,一个简单,一个更复杂和安全.并分别给出了两个方案的解析和测试程序.一般大家可以根据自己的项目的实际需要,自行定义自己的密码正则约定. 前言 用户注册时,都 ...

  3. HDU 2256Problem of Precision(矩阵快速幂)

    题意 求$(\sqrt{2} + \sqrt{3})^{2n} \pmod {1024}$ $n \leqslant 10^9$ Sol 看到题解的第一感受:这玩意儿也能矩阵快速幂??? 是的,它能q ...

  4. window之间、iframe之间的JS通信

    一.Window之间JS通信 在开发项目过程中,由于要引入第三方在线编辑器,所以需要另外一个窗口(window),而且要求打开的window要与原来的窗口进行js通信,那么如何实现呢? 1.在原窗口创 ...

  5. Outlook 客户端无法通过 MAPI over HTTP协议 连接

    随着Exchange 版本更新升级,是否进行验证客户端建立MapiHttp连接所需的服务器设置已正确配置.即使服务器,负载均衡器和反向代理的所有设置都正确,您可能会遇到连接到Exchange Serv ...

  6. 【Troubleshooting Case】Exchange Server 组件状态应用排错?

    在Exchange 2013中,引入了“服务器组件状态”的概念.服务器组件状态从运行环境的角度提供对组成Exchange Server的组件的状态的精细控制. 日常排错时,常常会把Exchange 服 ...

  7. MySQL查询示例

    use test; create table t1(tid smallint(5) unsigned auto_increment,tname varchar(50),tkecheng varchar ...

  8. windows自定义快速启动(运行)命令

    自定义运行(windows键+R)里面命令,启动设置的程序,如图: 它的设置方法有两种: 第一种设置方法: 第1步:在任意地方创建一个文件夹(建议在D盘根目录创建),文件夹的名称可自定义没有特殊限制, ...

  9. Meaningful Mean

    You are given an integer sequence of length N, a= {a1,a2,…,aN}, and an integer K.a has N(N+1)⁄2 non- ...

  10. CPP-网络/通信:用CMarkup类操纵XML

      首先到http://www.firstobject.com/下载CMarkup教学版,解压后里面是一个DEMO,将Markup.h .cpp拷贝并添加到工程中,第一次编译可能会出现预编译错误,解决 ...