BZOJ 4817 [Sdoi2017]树点涂色 ——LCT 线段树
同BZOJ3779。
SDOI出原题,还是弱化版的。
吃枣药丸
#include <map>
#include <cmath>
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define F(i,j,k) for (int i=j;i<=k;++i)
#define D(i,j,k) for (int i=j;i>=k;--i)
#define ll long long
#define mp make_pair
#define maxn 200005 int n,m,data[maxn]; namespace Tree{
int h[maxn],to[maxn],ne[maxn],f[maxn][21],en=0,dep[maxn];
int id[maxn],in[maxn],out[maxn],tot=0;
void add(int a,int b)
{to[en]=b;ne[en]=h[a];h[a]=en++;}
void dfs(int o)
{
in[o]=++tot; id[tot]=o;
for (int i=h[o];i>=0;i=ne[i])
if (to[i]!=f[o][0])
f[to[i]][0]=o,dep[to[i]]=dep[o]+1,dfs(to[i]);
out[o]=tot;
}
void init()
{
F(i,1,20)F(j,1,n)f[j][i]=f[f[j][i-1]][i-1];
F(i,1,n) data[in[i]]=dep[i];
// F(i,1,n) printf("%d ",id[i]); printf("\n");
// F(i,1,n) printf("%d ",data[i]);printf("\n");
}
int LCA(int a,int b)
{
if (dep[a]<dep[b]) swap(a,b);
int dist=dep[a]-dep[b];
D(i,20,0) if ((dist>>i)&1) a=f[a][i];
if (a==b) return a;
D(i,20,0) if (f[a][i]!=f[b][i]) a=f[a][i],b=f[b][i];
return f[b][0];
}
} namespace SegTree{
int mx[maxn<<3],tag[maxn<<3];
void update(int o)
{mx[o]=max(mx[o<<1],mx[o<<1|1]);}
void pushdown(int o)
{
if (tag[o]!=0)
{
tag[o<<1]+=tag[o];
tag[o<<1|1]+=tag[o];
mx[o<<1]+=tag[o];
mx[o<<1|1]+=tag[o];
tag[o]=0;
}
}
void build(int o,int l,int r)
{
if (l==r)
{
mx[o]=data[l];
tag[o]=0;
return ;
}
pushdown(o);
int mid=l+r>>1;
build(o<<1,l,mid);
build(o<<1|1,mid+1,r);
update(o);
}
void modify(int o,int l,int r,int L,int R,int f)
{
if (L<=l&&r<=R)
{
tag[o]+=f;
mx[o]+=f;
return;
}
pushdown(o);
int mid=l+r>>1;
if (R<=mid) return modify(o<<1,l,mid,L,R,f),update(o);
else if (L>mid) return modify(o<<1|1,mid+1,r,L,R,f),update(o);
else return modify(o<<1,l,mid,L,R,f),modify(o<<1|1,mid+1,r,L,R,f),update(o);
}
void add(int a,int f)
{if (!a) return ;modify(1,1,n,Tree::in[a],Tree::out[a],f);}
int querymx(int o,int l,int r,int L,int R)
{
if (L<=l&&r<=R) return mx[o];
pushdown(o);
int mid=l+r>>1;
if (R<=mid) return querymx(o<<1,l,mid,L,R);
else if (L>mid) return querymx(o<<1|1,mid+1,r,L,R);
else return max(querymx(o<<1,l,mid,L,R),querymx(o<<1|1,mid+1,r,L,R));
}
} namespace LCT{
int rev[maxn],fa[maxn],ch[maxn][2],sta[maxn],top=0;
bool isroot(int o)
{return ch[fa[o]][0]!=o&&ch[fa[o]][1]!=o;}
void rot(int x)
{
int y=fa[x],z=fa[y],l,r;
if (ch[y][0]==x) l=0; else l=1; r=l^1;
if (!isroot(y))
{
if (ch[z][0]==y) ch[z][0]=x;
else ch[z][1]=x;
}
fa[x]=z;fa[y]=x;fa[ch[x][r]]=y;
ch[y][l]=ch[x][r]; ch[x][r]=y;
}
void pushdown(int x)
{
if (rev[x])
{
rev[x]^=1;
rev[ch[x][0]]^=1;
rev[ch[x][1]]^=1;
swap(ch[x][0],ch[x][1]);
}
}
void splay(int x)
{
sta[top=1]=x;
for (int i=x;!isroot(i);i=fa[i]) sta[++top]=fa[i];
while(top) pushdown(sta[top--]); while (!isroot(x))
{
int y=fa[x];
if (!isroot(y))
{
int z=fa[y];
if (ch[z][0]==y^ch[y][0]==x) rot(x);
else rot(y);
}
rot(x);
}
}
int find(int x)
{
pushdown(x);
while (ch[x][0]) x=ch[x][0],pushdown(x);
return x;
}
void access(int x)
{
for (int t=0;x;t=x,x=fa[x])
{
splay(x);
SegTree::add(find(ch[x][1]),1);
ch[x][1]=t;
SegTree::add(find(ch[x][1]),-1);
}
}
} int opt,x,y; int main()
{
scanf("%d%d",&n,&m);
memset(Tree::h,-1,sizeof Tree::h);
F(i,2,n)
{
int a,b;
scanf("%d%d",&a,&b);
Tree::add(a,b);
Tree::add(b,a);
}
Tree::dep[1]=1;Tree::dfs(1);Tree::init();
F(i,1,n) LCT::fa[i]=Tree::f[i][0];
SegTree::build(1,1,n);
F(i,1,m)
{
scanf("%d",&opt);
// cout<<opt<<endl;
switch(opt)
{
case 1: scanf("%d",&x); LCT::access(x); break;
case 2:
scanf("%d%d",&x,&y);
printf("%d\n",SegTree::querymx(1,1,n,Tree::in[x],Tree::in[x])+SegTree::querymx(1,1,n,Tree::in[y],Tree::in[y])+1-2*SegTree::querymx(1,1,n,Tree::in[Tree::LCA(x,y)],Tree::in[Tree::LCA(x,y)])); break;
case 3: scanf("%d",&x); printf("%d\n",SegTree::querymx(1,1,n,Tree::in[x],Tree::out[x]));break;
}
}
}
BZOJ 4817 [Sdoi2017]树点涂色 ——LCT 线段树的更多相关文章
- [Sdoi2017]树点涂色 [lct 线段树]
[Sdoi2017]树点涂色 题意:一棵有根树,支持x到根染成新颜色,求x到y颜色数,求x子树里点到根颜色数最大值 考场发现这个信息是可减的,但是没想到lct 特意设计成lct的形式! 如何求颜色数? ...
- 【BZOJ4817】[Sdoi2017]树点涂色 LCT+线段树
[BZOJ4817][Sdoi2017]树点涂色 Description Bob有一棵n个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义一条路径的权值是:这条路 ...
- 【BZOJ4817】【SDOI2017】树点涂色 [LCT][线段树]
树点涂色 Time Limit: 10 Sec Memory Limit: 128 MB[Submit][Status][Discuss] Description Bob有一棵n个点的有根树,其中1 ...
- BZOJ 4817 [SDOI2017]树点涂色 (LCT+线段树维护dfs序)
题目大意:略 涂色方式明显符合$LCT$里$access$操作的性质,相同颜色的节点在一条深度递增的链上 用$LCT$维护一个树上集合就好 因为它维护了树上集合,所以它别的啥都干不了了 发现树是静态的 ...
- [SDOI2017][bzoj4817] 树点涂色 [LCT+线段树]
题面 传送门 思路 $LCT$ 我们发现,这个1操作,好像非常像$LCT$里面的$Access$啊~ 那么我们尝试把$Access$操作魔改成本题中的涂色 我们令$LCT$中的每一个$splay$链代 ...
- BZOJ4817[Sdoi2017]树点涂色——LCT+线段树
题目描述 Bob有一棵n个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义一条路 径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜色.Bob可能会进 ...
- bzoj4817 & loj2001 [Sdoi2017]树点涂色 LCT + 线段树
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4817 https://loj.ac/problem/2001 题解 可以发现这个题就是 bzo ...
- 【bzoj4817】树点涂色 LCT+线段树+dfs序
Description Bob有一棵n个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义一条路 径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜色. ...
- BZOJ 4817: [Sdoi2017]树点涂色(lct+线段树)
传送门 解题思路 跟重组病毒这道题很像.只是有了一个询问\(2\)的操作,然后询问\(2\)的答案其实就是\(val[x]+val[y]-2*val[lca(x,y)]+1\)(画图理解).剩下的操作 ...
随机推荐
- codeforce Gym 100500I Hall of Fame (水)
题意:统计一些串中,字母的出现频率,不分大小写,找出现频率最高5个字符(相同频率优先取字典序大的),把他们的对应的值加起来判断以下是否大于62. 没出现的不算. #include<cstdio& ...
- bootstrap 警告(Alerts)
本章将讲解警告(Alerts)以及bootstrap所提供的用于警告的class类.警告(Alerts)向用户提供了一种定义消息样式的方式.它们为典型的用户操作提供了上下文信息反馈. 您可以为警告框添 ...
- 瀑布流封装(仿写UITableView)
本篇文章将会仿照苹果系统提供的UITableView类,封装一个瀑布流效果的控件!!! 该控件和系统的UITableView是相同级别的 (继承自系统的UIScrollView) GitHub中Dem ...
- PAT 乙级 1088
题目 题目链接:PAT 乙级 1088 题解 比较简单的一道题,下面来简单说说思路: 因为甲确定是一个两位数,因此通过简单的暴力循环求解甲的值,又根据题设条件“把甲的能力值的 2 个数字调换位置就是乙 ...
- Django项目SECRET_KEY等敏感信息保存
在我们做完django项目后,向生产环境部署时,为了避免一些敏感信息被有心人利用,我们应该将其保护起来,比如说在settings配置中的一些密码等内容存在操作系统内,通过调用来使用,比如下面这种做法: ...
- mysql中的的按小数位截取
format()函数返回类型是字符串,满三位会加一个逗号. 针对数字类型转换建议使用 convert或者cast函数,用法如下: format(param, 2) (不建议) convert(para ...
- 标准C++(4)继承
一.继承的作用 若A类继承了B类,可以使A类获得B类中的部分成员变量和成员函数,这能使程序员在已有类的基础上重新定义新的类.继承是类的重要特性,当A类继承了B类,我们称A类为派生类或子类,B类为基类或 ...
- django开发之model篇-Field类型讲解
今天介绍一下django开发中,定义模型时用到的相关字段类型和字段选项. 先说说常用的字段类型:1) AutoField: 自增字段类型,当自定义自增类型的id时,可以使用此类型:2) BigAuto ...
- destoon 多表联合查询时出现解析错误,parse_str函数解析错误
数据库前缀 wb_ 标签 ,调用文章时获取评论数量 <!--{php $tags=tag("table=article_24 a left join wb_comment_stat ...
- java的一些相关介绍(2013-10-07-163 写的日志迁移
java是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由Sun Microsystems公司于1995年5月推出的Java程序设计语言和Java平台(即JavaSE, JavaEE, Jav ...