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 ...
随机推荐
- spring boot Filter过滤器的简单使用
springboot使用Filter过滤器有两种方式: 一种是实现Filter接口然后通过@Component注解向项目加入过滤器 另一种是通过配置类来配置过滤器 @Component public ...
- HDU 2256Problem of Precision(矩阵快速幂)
题意 求$(\sqrt{2} + \sqrt{3})^{2n} \pmod {1024}$ $n \leqslant 10^9$ Sol 看到题解的第一感受:这玩意儿也能矩阵快速幂??? 是的,它能q ...
- mui自定义事件实例
监听自定义事件(接收页面应用) 添加自定义事件监听操作和标准js事件监听类似,可直接通过window对象添加,如下: window.addEventListener('customEvent',fun ...
- Android Google Map API使用的八个步骤
本系列教程将分为两部分,第一部分是指导用户使用Mapview控件进行编程,其中包括了如何获得Google Map API,如何使用该API进行简单的开发,如何获得用户当前所在的位置.第二部分则包括如何 ...
- django之模版的自定义函数
- 自定义函数 simple_tag a. app下创建templatetags目录 b. 任意xxoo.py文件 c. 创建template对象 register d. __author__ = ' ...
- noip模拟赛#15
#15 T1:a[i]>=a[i/2].输出a的最大字典序 =>可以发现这是二叉树的情况那么就先预处理出每个点有多少个儿子然后递归处理就可以了. #include<cstdio> ...
- 认识CoreData—初识CoreData
http://www.cocoachina.com/ios/20160729/17245.html 这段时间公司一直比较忙,和组里小伙伴一起把公司项目按照之前逻辑重写了一下.由于项目比较大,还要兼顾之 ...
- C#textbox允许换行
要让一个TextBox显示多行文本就得把它的Multiline属性设置为true就行
- Happy Equation
Source: The 10th Shandong Provincial Collegiate Programming Contest 题解: 因为2^p为偶数,所以a,x的奇偶性相同 1.当a为奇数 ...
- opencv将rgb图像转换成灰度图
python写法: import cv2 img = cv2.imread(img_dir, cv2.IMREAD_GRAYSCALE) cv2.imwrite(dis_dir, img) imrea ...