loj2001 「SDOI2017」树点涂色
#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」树点涂色的更多相关文章
- 「SDOI2017」树点涂色 解题报告
「SDOI2017」树点涂色 我sb的不行了 其实一开始有一个类似动态dp的想法 每个点维护到lct树上到最浅点的颜色段数,然后维护一个\(mx_{0,1}\)也就是是否用虚儿子的最大颜色 用个set ...
- 【BZOJ4817】【SDOI2017】树点涂色 [LCT][线段树]
树点涂色 Time Limit: 10 Sec Memory Limit: 128 MB[Submit][Status][Discuss] Description Bob有一棵n个点的有根树,其中1 ...
- [SDOI2017][bzoj4817] 树点涂色 [LCT+线段树]
题面 传送门 思路 $LCT$ 我们发现,这个1操作,好像非常像$LCT$里面的$Access$啊~ 那么我们尝试把$Access$操作魔改成本题中的涂色 我们令$LCT$中的每一个$splay$链代 ...
- [Sdoi2017]树点涂色 [lct 线段树]
[Sdoi2017]树点涂色 题意:一棵有根树,支持x到根染成新颜色,求x到y颜色数,求x子树里点到根颜色数最大值 考场发现这个信息是可减的,但是没想到lct 特意设计成lct的形式! 如何求颜色数? ...
- P3703 [SDOI2017]树点涂色
P3703 [SDOI2017]树点涂色 链接 分析: 首先对于询问,感觉是线段树维护dfs序,每个点记录到根的颜色个数.第二问差分,第三问区间取max. 那么考虑修改,每次将一个点的颜色变成和父节点 ...
- 【LG3703】[SDOI2017]树点涂色
[LG3703][SDOI2017]树点涂色 题面 洛谷 题解 更博辣,更博辣!!! 猪年的第一篇博客 一次只能染根到\(x\),且染的颜色未出现过 这句话是我们解题的关键. 设\(x\)到根的颜色数 ...
- [BZOJ4817][SDOI2017]树点涂色(LCT+DFS序线段树)
4817: [Sdoi2017]树点涂色 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 692 Solved: 408[Submit][Status ...
- 【BZOJ4817】[Sdoi2017]树点涂色 LCT+线段树
[BZOJ4817][Sdoi2017]树点涂色 Description Bob有一棵n个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义一条路径的权值是:这条路 ...
- [Bzoj4817] [Sdoi2017]树点涂色 (LCT神题)
4817: [Sdoi2017]树点涂色 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 629 Solved: 371[Submit][Status ...
随机推荐
- Windows及Linux环境搭建Redis集群
一.Windows环境搭建Redis集群 参考资料:Windows 环境搭建Redis集群 二.Linux环境搭建Redis集群 参考资料:Redis Cluster的搭建与部署,实现redis的分布 ...
- 快速搭建高可用 LNMP Web应用基础架构
云服务器费用:查看费用 产品详情 产品介绍 本镜像是根据Azure Resource Manager模板创建的,基于资源组下的高可用web系统,主要包括前端web负载均 ...
- python3操作excel02(对excel的基础操作,进行简单的封装)3
#!/usr/bin/env python# -*- coding:UTF-8 -*- import requestsfrom bs4 import BeautifulSoupfrom bs4 imp ...
- SQL Server AlwaysON从入门到进阶(6)——分析和部署AlwaysOn Availability Group
前言: 本节是整个系列的重点文章,到现在,读者应该已经对整个高可用架构有一定的了解,知道独立的SQL Server实例和基于群集的SQL Server FCI的区别.上一节已经介绍了如何安装SQL ...
- Cause: java.lang.UnsupportedOperationException
运行web项目的时候出现以下错误: ### Cause: java.lang.UnsupportedOperationException at org.mybatis.spring.MyBati ...
- JNI接口的使用(简单版)
详见 http://b6ec263c.wiz03.com/share/s/2SX2oY0nX4f32CY5ax1bapaL2Qtc5q0tIQjG2yfwaU1MX4Ye
- 【UML】活动图Activity diagram(转)
前言 在UML状态图的总结中说道,活动图和状态图是紧密相关的.它与流程图也有很多相似的地方. 定义 活动图是状态图的一种特殊形式.其中所有或多数状态都是活动状态,而且所有或多数转移都在源状态中的活动完 ...
- Codeforces Round #313 (Div. 2) A.B,C,D,E Currency System in Geraldion Gerald is into Art Gerald's Hexagon Equivalent Strings
A题,超级大水题,根据有没有1输出-1和1就行了.我沙茶,把%d写成了%n. B题,也水,两个矩形的长和宽分别加一下,剩下的两个取大的那个,看看是否框得下. C题,其实也很简单,题目保证了小三角形是正 ...
- bzoj3209:3209: 花神的数论题
觉得还是数位dp的那种解题形式但是没有认真的想,一下子就看题解.其实还是设置状态转移.一定要多思考啊f[i][j]=f[i-1][j]+g[i-1][j] g[i][j]=f[i-1][j-1]+g[ ...
- Python——三目运算符
一.三目运算符 1.if语句三目运算符语法格式 Python可以通过if'语句来实现三目运算符的功能,因此可以把这种if语句当做三目运算符,具体语法格式如下: 返回True执行 if 表达式 else ...