震惊!LCT还能这么用!

这个颜色修改的特点是点到根

搜刮一下性质,颜色从根到某个点是分层次单调增的,而且同一个点的两个不同儿子不会有相同颜色,也就是相同颜色的点是树上自上往下的一条链

前面这些都是次要的,主要是能不能想到并不和LCT的access操作很像

那么我们可以让一棵splay维护一条相同颜色的链,那么access修改儿子的时候顺便改一改点到根的颜色数

dfs序+线段树维护子树中的最大值

第二个问直接暴力跳链算就行了

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
const int _=1e2;
const int maxn=1e5+_;
const int fbin=(1<<17)+_;
const int mbit=30;
int n;int L[maxn],R[maxn];
struct segnode{int mx,la;};
struct segtree
{segnode tr[2*fbin];void pushdown(int now){int lc=(now<<1),rc=(now<<1|1);if(tr[now].la!=0){tr[lc].mx+=tr[now].la,tr[lc].la+=tr[now].la;tr[rc].mx+=tr[now].la,tr[rc].la+=tr[now].la;tr[now].la=0;}}void update(int now){int lc=(now<<1),rc=(now<<1|1);tr[now].mx=max(tr[lc].mx,tr[rc].mx);}void change(int now,int ql,int qr,int l,int r,int c){if(ql==l&&qr==r){tr[now].mx+=c,tr[now].la+=c;return ;}pushdown(now);int mid=(ql+qr)/2,lc=(now<<1),rc=(now<<1|1);if(r<=mid)  change(lc,ql,mid,l,r,c);else if(mid+1<=l)change(rc,mid+1,qr,l,r,c);else change(lc,ql,mid,l,mid,c),change(rc,mid+1,qr,mid+1,r,c);update(now);}int getmax(int now,int ql,int qr,int l,int r){if(ql==l&&qr==r)return tr[now].mx;pushdown(now);int mid=(ql+qr)/2,lc=(now<<1),rc=(now<<1|1);if(r<=mid)  return getmax(lc,ql,mid,l,r);else if(mid+1<=l)return getmax(rc,mid+1,qr,l,r);else return max(getmax(lc,ql,mid,l,mid),getmax(rc,mid+1,qr,mid+1,r));}
}S;struct trnode{int f,son[2];bool fz;};
struct LCT
{trnode tr[maxn];void rev(int x){if(tr[x].fz){int lc=tr[x].son[0],rc=tr[x].son[1];swap(tr[lc].son[0],tr[lc].son[1]),tr[lc].fz^=1;swap(tr[rc].son[0],tr[rc].son[1]),tr[rc].fz^=1;tr[x].fz=false;}}void rotate(int x,int w){int f=tr[x].f,ff=tr[f].f;int R,r;R=f,r=tr[x].son[w];tr[R].son[1-w]=r;if(r!=0)tr[r].f=R;R=ff,r=x;if(tr[ff].son[0]==f)tr[R].son[0]=r;else if(tr[ff].son[1]==f)tr[R].son[1]=r;tr[r].f=R;R=x,r=f;tr[R].son[w]=r;tr[r].f=R;}int tlen,tmp[maxn];bool islight(int x){if(tr[x].f==0||(tr[tr[x].f].son[0]!=x&&tr[tr[x].f].son[1]!=x))return true;return false;}void splay(int x,int rt){tlen=0;int i=x;while(x!=rt&& !islight(i) )tmp[++tlen]=i,i=tr[i].f;tmp[++tlen]=i;while(tlen!=0)rev(tmp[tlen]),tlen--;while(tr[x].f!=rt&& !islight(x) ){int f=tr[x].f,ff=tr[f].f;if(ff==rt||islight(f)){if(tr[f].son[0]==x)rotate(x,1);else rotate(x,0);}else{if(tr[ff].son[0]==f&&tr[f].son[0]==x)rotate(f,1),rotate(x,1);else if(tr[ff].son[1]==f&&tr[f].son[1]==x)rotate(f,0),rotate(x,0);else if(tr[ff].son[0]==f&&tr[f].son[1]==x)rotate(x,0),rotate(x,1);else if(tr[ff].son[1]==f&&tr[f].son[0]==x)rotate(x,1),rotate(x,0);}}}//~~~~~~~~~~~~~~~~~~~~~~~~~~splay~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int findroot(int x){splay(x,0);while(tr[x].son[0]!=0)x=tr[x].son[0];return x;}void access(int x){int y=0,u,rt;while(x!=0){splay(x,0);u=tr[x].son[1];if(y!=0)rt=findroot(y),S.change(1,1,n,L[rt],R[rt],-1);splay(x,0);tr[x].son[1]=y;if(u!=0)rt=findroot(u),S.change(1,1,n,L[rt],R[rt],1);y=x,x=tr[x].f;}}//~~~~~~~~~~~~~~~~~~~~~~~~~~lct~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~int getsum(int x,int z){int ans=1;while(findroot(x)!=findroot(z)){splay(x,0);x=tr[x].f;ans++;}return ans;}//~~~~~~~~~~~~~~~~~~~~~~~~~~~~solve~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
}lct;//--------------------------------------------data structure--------------------------------------------------------------struct node
{int x,y,next;
}a[2*maxn];int len,last[maxn];
void ins(int x,int y)
{len++;a[len].x=x;a[len].y=y;a[len].next=last[x];last[x]=len;
}
int z,f[mbit][maxn],dep[maxn];
void dfs(int x)
{for(int i=1;(1<<i)<=dep[x];i++)f[i][x]=f[i-1][f[i-1][x]];L[x]=++z;for(int k=last[x];k;k=a[k].next){int y=a[k].y;if(y!=f[0][x]){lct.tr[y].f=x;dep[y]=dep[x]+1;f[0][y]=x;dfs(y);}}R[x]=z;S.change(1,1,n,L[x],R[x],1);
}
int LCA(int x,int y)
{if(dep[x]<dep[y])swap(x,y);for(int i=25;i>=0;i--)if(dep[x]-dep[y]>=(1<<i))x=f[i][x];if(x==y)return x;for(int i=25;i>=0;i--)if(dep[x]>=(1<<i)&&f[i][x]!=f[i][y])x=f[i][x],y=f[i][y];return f[0][x];
}//---------------------------------------true tree------------------------------------------------------------int main()
{freopen("a.in","r",stdin);freopen("a.out","w",stdout);int Q,x,y;scanf("%d%d",&n,&Q); len=1;for(int i=1;i<n;i++){scanf("%d%d",&x,&y);ins(x,y),ins(y,x);}dfs(1);int op;while(Q--){scanf("%d",&op);if(op==1){scanf("%d",&x);lct.access(x);}else if(op==2){scanf("%d%d",&x,&y);int z=LCA(x,y);printf("%d\n",lct.getsum(x,z)+lct.getsum(y,z)-1);}else{scanf("%d",&x);printf("%d\n",S.getmax(1,1,n,L[x],R[x]));}}return 0;
}

转载于:https://www.cnblogs.com/AKCqhzdy/p/10453207.html

bzoj4817: [Sdoi2017]树点涂色相关推荐

  1. [Bzoj4817] [Sdoi2017]树点涂色 (LCT神题)

    4817: [Sdoi2017]树点涂色 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 629  Solved: 371 [Submit][Stat ...

  2. BZOJ 4817: [Sdoi2017]树点涂色

    4817: [Sdoi2017]树点涂色 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 273  Solved: 164 [Submit][Stat ...

  3. Bzoj4817:[SDOI2017]树点涂色

    题面 Bzoj Sol 做个转化 最开始都是虚边 操作\(1\)就是\(LCT\)里的\(Access\)操作 求的就是路径上虚边的个数+1 然后就好办了 用树链剖分+线段树来维护每个点到根虚边的个数 ...

  4. BZOJ 4817: [Sdoi2017]树点涂色(LCT+树剖+线段树)

    题目描述 Bob有一棵 nn 个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同. 定义一条路径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜色. Bob ...

  5. 【BZOJ4817】【SDOI2017】树点涂色 [LCT][线段树]

    树点涂色 Time Limit: 10 Sec  Memory Limit: 128 MB [Submit][Status][Discuss] Description Bob有一棵n个点的有根树,其中 ...

  6. 【线段树】【LCT】【LCA】树点涂色(luogu 3703)

    树点涂色 luogu 3703 题目大意 给出一棵树,每个节点的初始颜色不同,做若干操作: 1.在一个点到根节点路径上染上一种新的颜色 2.查询一条路径上有多少种不同的颜色 3.查询一个点x,使该点到 ...

  7. [BZOJ4817]树点涂色

    第一个操作比较麻烦,但可以看出它和lct里的access操作差不多,所以可以利用lct的性质巧妙维护操作1 直接用lct维护树中同颜色的链(因为染色操作是从$x$染到根所以同颜色的点一定形成一条链), ...

  8. P3703-[SDOI2017]树点涂色【LCT,线段树】

    正题 题目链接:https://www.luogu.com.cn/problem/P3703 题目大意 nnn个点的一棵树开始所有点有不同的颜色,mmm次操作 将根节点到xxx节点的路径上染上一种新的 ...

  9. ​LeetCode刷题实战276:栅栏涂色

    算法的重要性,我就不多说了吧,想去大厂,就必须要经过基础知识和业务逻辑面试+算法面试.所以,为了提高大家的算法能力,这个公众号后续每天带大家做一道算法题,题目就从LeetCode上面选 ! 今天和大家 ...

最新文章

  1. nginx lua redis 访问频率限制(转)
  2. pagefile.sys解析
  3. Android activity生命周期
  4. hdu1978 简单记忆化搜索
  5. mysql事务和锁InnoDB
  6. 图像处理与识别技术的应用
  7. python 检测exe是否未响应_第002篇:Python的安装
  8. 数论四之综合训练——Magic Pairs,Crime Management,Top Secret,组合数问题
  9. javaone_JavaOne 2012:调查JVM水晶球
  10. 元气骑士如何获得机器人成就皮肤_元气骑士:9大英雄特典皮肤2技能特效优化,“颜控”玩家有福了...
  11. [深度学习-实践]Tensorflow 2.x应用ResNet SeNet网络训练cifar10数据集的模型在测试集上准确率 86%-87%,含完整代码
  12. Media Player Classic - HC 源代码分析 4:核心类 (CMainFrame)(3)
  13. 去掉Windows Media Player 12 中”挖挖哇“网址的方法
  14. 工作流软件是未来web的支柱
  15. JAVAWeb开发之Servlet-19.Filter
  16. 手机计算机文件夹加密文件,如何给手机以及电脑文件加密?
  17. LightOJ1220 —— 质因数分解
  18. 行为识别(CVPR2020南京大学腾讯) ~ TEA论文笔记 ~《TEA: Temporal Excitation and Aggregation for Action Recognition》
  19. Apache的性能解读
  20. 西南大学统考英语计算机有答案吗,西南大学1806课程[0002]《英语》机考A卷答案参考...

热门文章

  1. linux shell字符串及字符串长度获取方式
  2. Ansible Playbook企业案例:利用 playbook 安装 nginx、安装和卸载 httpd、安装mysql
  3. vscode技巧、vscode教程、vscode使用技巧
  4. Go语言web框架beego:目录说明
  5. zookeeper 分布式协调服务
  6. 软件测试mysql常用语句_测试中常用到的SQL语句(Oracle)
  7. java解决特殊字符输出
  8. Qt for Android Splash启动页最简单延时关闭
  9. java相对目录_java相对目录和绝对目录解析
  10. 无效0_12位浙江高考生成绩被教育考试院判定无效,0分收场的原因很可惜