SDOI2017树点染色
发现1操作很像lct中的access,然后它每次染的又是一个新颜色,因此同一个颜色就在同一颗splay里了,且一个点到根的权值val[i]也就是到根路径上虚边的个数,然后看access时会对哪些点的val[i]产生影响。
以下的原儿子表示原来与x在同一颗splay中的儿子 (注意不是splay中x的儿子,是原树中x的儿子,即splay中x的后继)。
当x断开与它原儿子所在splay的连接时,原儿子的子树val都要+1,接上的新儿子的splay,新儿子所在子树val要-1。
对于2操作,相当于统计x~y路径上虚边个数+1,val[x]+val[y]-2*val[lca]+1即是。
对于3操作在子树中找个最大的val即可。
val的话可以用线段树维护。
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<vector>
#include<algorithm>
#include<queue>
#include<cmath>
#include<stack>
#include<map>
#define P puts("lala")
#define cp cerr<<"lala"<<endl
#define ln putchar('\n')
#define sp putchar(' ')
#define pb push_back
#define fi first
#define se second
#define mkp make_pair
using namespace std;
typedef pair<int,int> pii;
inline void read(int &re)
{
char ch=getchar();int g=1;
while(ch<'0'||ch>'9') {if(ch=='-')g=-1;ch=getchar();}
re=0;
while(ch<='9'&&ch>='0') re=(re<<1)+(re<<3)+(ch^48),ch=getchar();
re*=g;
}
typedef long long ll;
inline void read(ll &re)
{
char ch=getchar();ll g=1;
while(ch<'0'||ch>'9') {if(ch=='-')g=-1;ch=getchar();}
re=0;
while(ch<='9'&&ch>='0') re=(re<<1)+(re<<3)+ch-48ll,ch=getchar();
re*=g;
} const int N=100050;
int maxv[N<<2],add[N<<2],fa[N],ch[N][2];
int siz[N],dfn[N],tot=0,is[N],f[N][21],n,dep[N]; int head[N],cnt=0;
struct node
{
int to,next;
}e[N<<1];
inline void add_edge(int x,int y)
{
e[++cnt]=(node){y,head[x]};head[x]=cnt;
e[++cnt]=(node){x,head[y]};head[y]=cnt;
} void build(int o,int l,int r)
{
if(l==r) {maxv[o]=dep[is[l]];return ;}
int mid=l+r>>1;
build(o<<1,l,mid); build(o<<1|1,mid+1,r);
maxv[o]=max(maxv[o<<1],maxv[o<<1|1]);
}
void pushdown(int o)
{
if(add[o])
{
add[o<<1]+=add[o]; add[o<<1|1]+=add[o];
maxv[o<<1]+=add[o]; maxv[o<<1|1]+=add[o];
add[o]=0;
}
}
void update(int o,int l,int r,int x,int y,int k) //add k
{
if(x<=l&&r<=y) {add[o]+=k;maxv[o]+=k;return ;}
pushdown(o);
int mid=l+r>>1;
if(x<=mid) update(o<<1,l,mid,x,y,k);
if(y>mid) update(o<<1|1,mid+1,r,x,y,k);
maxv[o]=max(maxv[o<<1],maxv[o<<1|1]);
}
int query(int o,int l,int r,int x,int y)
{
if(x<=l&&r<=y) return maxv[o];
pushdown(o);
int mid=l+r>>1,ans=0;
if(x<=mid) ans=query(o<<1,l,mid,x,y);
if(y>mid) ans=max(ans,query(o<<1|1,mid+1,r,x,y));
return ans;
} inline bool ge(int x) {return ch[fa[x]][1]==x;}
inline bool isroot(int x) {return ch[fa[x]][1]!=x&&ch[fa[x]][0]!=x;}
inline void rotate(int x)
{
int f=fa[x],g=fa[f],wh=ge(x);
if(!isroot(f)) ch[g][ch[g][1]==f]=x;
ch[f][wh]=ch[x][wh^1]; fa[ch[f][wh]]=f;
ch[x][wh^1]=f; fa[f]=x;
fa[x]=g;
}
void splay(int x)
{
for(int f;(f=fa[x])&&!isroot(x);rotate(x))
if(!isroot(f)) rotate(ge(x)==ge(f)?f:x);
} int nex(int x)
{
x=ch[x][1];
while(ch[x][0]) x=ch[x][0];
return x;
} void access(int x)
{
for(int t=0;x;t=x,x=fa[x])
{
splay(x);
if(ch[x][1])
{
int y=nex(x);
update(1,1,n,dfn[y],dfn[y]+siz[y]-1,1);
}
ch[x][1]=t;
if(ch[x][1])
{
int y=nex(x);
update(1,1,n,dfn[y],dfn[y]+siz[y]-1,-1);
}
}
} void dfs(int u,int dad,int d)
{
fa[u]=dad; f[u][0]=dad;
dfn[u]=++tot; is[tot]=u;
siz[u]=1; dep[u]=d;
for(int i=head[u];i;i=e[i].next)
{
int v=e[i].to;
if(v==dad) continue;
dfs(v,u,d+1);
siz[u]+=siz[v];
}
} int lca(int x,int y)
{
if(dep[x]<dep[y]) swap(x,y);
int d=dep[x]-dep[y];
for(int i=19;i>=0;--i) if(d&(1<<i)) x=f[x][i];
if(x==y) return x;
for(int i=19;i>=0;--i) if(f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];
return f[x][0];
} int ask(int x,int y)
{
int o=lca(x,y);
return query(1,1,n,dfn[x],dfn[x])+query(1,1,n,dfn[y],dfn[y])
-query(1,1,n,dfn[o],dfn[o])*2;
} int main()
{
#ifndef ONLINE_JUDGE
freopen("1.in","r",stdin);freopen("1.out","w",stdout);
#endif
int i,j,opt,T;
read(n);read(T);
for(i=1;i<n;++i)
{
int x,y;read(x);read(y);
add_edge(x,y);
} dfs(1,0,0);
for(j=1;j<=19;++j) for(i=1;i<=n;++i) f[i][j]=f[f[i][j-1]][j-1]; build(1,1,n);
for(int cas=1;cas<=T;++cas)
{
read(opt);
if(opt==1)
{
int x;read(x);
access(x);
}
else if(opt==2)
{
int x,y;read(x);read(y);
printf("%d\n",ask(x,y)+1);
}
else
{
int x;read(x);
printf("%d\n",query(1,1,n,dfn[x],dfn[x]+siz[x]-1)+1);
}
}
return 0;
}
/* */
SDOI2017树点染色的更多相关文章
- SDOI2017 树点染色
\[SDOI2017 树点染色\] 题目描述 Bob 有一棵 $ n $ 个点的有根树,其中 $ 1 $ 号点是根节点.Bob 在每个节点上涂了颜色,并且每个点上的颜色不同. 定义一条路径的权值是,这 ...
- loj2001[SDOI2017]树点染色
题意:给你一棵树,一开始每个点上的颜色互不相同.三种操作:op1:x到根的路径上的点都染上一种新的颜色.op2:设一条路径的权值为val(x,y),求x到y路径的val.op3:询问x的子树中最大的到 ...
- 洛谷3703 [SDOI2017] 树点染色 【LCT】【线段树】
题目分析: 操作一很明显等价于LCT上的access操作,操作二是常识,操作三转化到dfs序上求最大值也是常识.access的时候顺便在线段树中把对应部分-1,把右子树的子树+1即可. 代码: #in ...
- codevs 5963 [SDOI2017]树点染色
[题解]: #include<cstdio> #include<cstring> #include<iostream> using namespace std; ...
- [Sdoi2017]树点涂色 [lct 线段树]
[Sdoi2017]树点涂色 题意:一棵有根树,支持x到根染成新颜色,求x到y颜色数,求x子树里点到根颜色数最大值 考场发现这个信息是可减的,但是没想到lct 特意设计成lct的形式! 如何求颜色数? ...
- P3703 [SDOI2017]树点涂色
P3703 [SDOI2017]树点涂色 链接 分析: 首先对于询问,感觉是线段树维护dfs序,每个点记录到根的颜色个数.第二问差分,第三问区间取max. 那么考虑修改,每次将一个点的颜色变成和父节点 ...
- codevs 1191 树轴染色 线段树区间定值,求和
codevs 1191 树轴染色 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.codevs.cn/problem/1191/ Des ...
- 【LG3703】[SDOI2017]树点涂色
[LG3703][SDOI2017]树点涂色 题面 洛谷 题解 更博辣,更博辣!!! 猪年的第一篇博客 一次只能染根到\(x\),且染的颜色未出现过 这句话是我们解题的关键. 设\(x\)到根的颜色数 ...
- HDU3974 Assign the task(多叉树转换为线段+线段树区间染色)
题目大意:有n个人,给你他们的关系(老板和员工),没有直属上司的人就是整个公司的领导者,这意味着n个人形成一棵树(多叉树).当一个人被分配工作时他会让他的下属也做同样的工作(并且立即停止手头正在做的工 ...
随机推荐
- 英特尔CPU系列
1.酷睿(Core)系列,主要应用于管理 3D.高级视频和照片编辑,玩复杂游戏,享受高分辨率 4K 显示. 2.奔腾(PenTIum)系列,主要应用于借助功能丰富的处理器,加快便携式 2 合 1 电脑 ...
- JVM学习之 内存结构
目录 一.引言 1.什么是JVM? 2.学习JVM有什么用 3.常见的JVM 4.学习路线 二.内存结构 1. 程序计数器 1.1 定义 1.2作用 2. 虚拟机栈 2.1定义 2.2栈内存溢出 2. ...
- 面试突击72:输入URL之后会执行什么流程?
在浏览器中输入 URL 之后,它会执行以下几个流程: 执行 DNS 域名解析: 封装 HTTP 请求数据包: 封装 TCP 请求数据包: 建立 TCP 连接(3 次握手): 参数从客户端传递到服务器端 ...
- 海豚调度5月Meetup:6个月重构大数据平台,帮你避开调度升级改造/集群迁移踩过的坑
当今许多企业都有着技术架构的DataOps程度不够.二次开发成本高.迁移成本高.集群部署混乱等情况,团队在技术选型之后发现并不适合自己的需求,但是迁移成本和难度又比较大,甚至前团队还留下了不少坑,企业 ...
- 如何在BI中增加“路线地图”并进行数据分析?
随着客户的需求越来越"百变",最近在做大屏设计的葡萄陷入了困境. 近期客户提出的需求是想在BI工具中增加 "路线地图"展示功能并进行数据分析. 不仅如此,这个& ...
- CSS 选择器(一):属性选择器
属性选择器的介绍 属性选择器顾名思义就是通过标签的属性来查找标签的选择器.让我们来回忆一下标签的属性是什么?HTML5 的所有标签共同拥有的属性叫作全局属性,除此之外还有标签自己拥有的属性,就叫作私有 ...
- 简单概述 TCP/IP 协议簇
前言 通信协议是计算机之间交换信息所使用的一种公共语言的规范和约定.Internet 的通信协议包含 100 多种相互关联的协议,但是 TCP 和 IP 是其中两个最核心的关键协议,所以把 Inter ...
- 一、JDK和JRE
JDK和JRE JDK=JRE+开发工具包: JRE=JVM+核心类库 如果只是运行Java程序,安装JRE即可:开发Java程序并运行则需要安装JDK.目前最稳定版本是JDK8.0,并且马上部分企业 ...
- 详解MySQL隔离级别
一个事务具有ACID特性,也就是(Atomicity.Consistency.Isolation.Durability,即原子性.一致性.隔离性.持久性),本文主要讲解一下其中的Isolation,也 ...
- 小样本利器3. 半监督最小熵正则 MinEnt & PseudoLabel代码实现
在前两章中我们已经聊过对抗学习FGM,一致性正则Temporal等方案,主要通过约束模型对细微的样本扰动给出一致性的预测,推动决策边界更加平滑.这一章我们主要针对低密度分离假设,聊聊如何使用未标注数据 ...