codevs 5963 [SDOI2017]树点染色
[题解]:
#include<cstdio> #include<cstring> #include<iostream> using namespace std; const int N=1e5+5; struct edge{int v,next;}e[N<<1];int tot,head[N],cur[N]; int n,m,top,st[N<<1]; inline int read(){int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f; } void add(int x,int y){e[++tot].v=y;e[tot].next=head[x];head[x]=tot;e[++tot].v=x;e[tot].next=head[y];head[y]=tot; } int dfs_cnt,dfn[N],end[N],pos[N]; int fa[N],fat[N][20],dep[N]; void dfs(){memcpy(cur,head,sizeof head);int x;st[++top]=1;dep[1]=1;while(top){ con:x=st[top];if(!dfn[x]) dfn[x]=++dfs_cnt;for(int &i=cur[x];i;){if(e[i].v==fa[x]){i=e[i].next;continue;} fa[e[i].v]=x;fat[e[i].v][0]=x;dep[e[i].v]=dep[x]+1;st[++top]=e[i].v;i=e[i].next;goto con;}end[x]=dfs_cnt; top--;}for(int i=1;i<=n;i++) pos[dfn[i]]=i; } const int M=N<<2; int mx[M],tag[M]; #define lch k<<1 #define rch k<<1|1 void build(int k,int l,int r){if(l==r){mx[k]=dep[pos[l]];return ;}int mid=l+r>>1;build(lch,l,mid);build(rch,mid+1,r);mx[k]=max(mx[lch],mx[rch]); } void pushdown(int k){if(!tag[k]) return ;mx[lch]+=tag[k];mx[rch]+=tag[k];tag[lch]+=tag[k];tag[rch]+=tag[k];tag[k]=0; } void plusx(int k,int l,int r,int x,int y,int val){if(l==x&&r==y){mx[k]+=val;tag[k]+=val;return ;}pushdown(k);int mid=l+r>>1;if(y<=mid) plusx(lch,l,mid,x,y,val);else if(x>mid) plusx(rch,mid+1,r,x,y,val);else plusx(lch,l,mid,x,mid,val),plusx(rch,mid+1,r,mid+1,y,val);mx[k]=max(mx[lch],mx[rch]); } int ask(int k,int l,int r,int p){if(l==r) return mx[k];pushdown(k);int mid=l+r>>1;if(p<=mid) return ask(lch,l,mid,p);else return ask(rch,mid+1,r,p); } int query(int k,int l,int r,int x,int y){if(l==x&&r==y) return mx[k];pushdown(k);int mid=l+r>>1;if(y<=mid) return query(lch,l,mid,x,y);else if(x>mid) return query(rch,mid+1,r,x,y);else return max(query(lch,l,mid,x,mid),query(rch,mid+1,r,mid+1,y)); } int siz[N],ch[N][2]; bool isroot(int x){return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x; } void rotate(int x){int y=fa[x],z=fa[y],l,r;l=(ch[y][1]==x);r=l^1;if(!isroot(y)) ch[z][ch[z][1]==y]=x;fa[x]=z;fa[y]=x;fa[ch[x][r]]=y;ch[y][l]=ch[x][r];ch[x][r]=y; } void splay(int x){while(!isroot(x)){int y=fa[x],z=fa[y];if(!isroot(y)){if((ch[y][0]==x)^(ch[z][0]==y)) rotate(x);else rotate(y);}rotate(x);} } int findmin(int x){if(!x) return 0;for(;ch[x][0];x=ch[x][0]);return x; } void access(int x){for(int y=0,z;x;y=x,x=fa[x]){splay(x);z=findmin(ch[x][1]);if(z) plusx(1,1,n,dfn[z],end[z],1);if(fa[x]){z=findmin(x);plusx(1,1,n,dfn[z],end[z],-1);}ch[x][1]=y;} } int lca(int a,int b){if(dep[a]<dep[b]) swap(a,b);int t=dep[a]-dep[b];for(int i=0;i<=18;i++){if((1<<i)&t){a=fat[a][i]; }}if(a==b) return a;for(int i=18;~i;i--){if(fat[a][i]!=fat[b][i]){a=fat[a][i];b=fat[b][i];}}return fat[a][0]; } int main(){n=read();m=read();for(int i=1,x,y;i<n;i++) x=read(),y=read(),add(x,y);dfs();build(1,1,n);for(int j=1;j<=18;j++){for(int i=1;i<=n;i++){fat[i][j]=fat[fat[i][j-1]][j-1];}}for(int i=1,opt,x,y,anc,ans;i<=m;i++){opt=read();x=read();if(opt==1) access(x);if(opt==2){y=read();anc=lca(x,y);ans=ask(1,1,n,dfn[x])+ask(1,1,n,dfn[y])-2*ask(1,1,n,dfn[anc])+1;printf("%d\n",ans);}if(opt==3) printf("%d\n",query(1,1,n,dfn[x],end[x]));}return 0; }
转载于:https://www.cnblogs.com/shenben/p/6696504.html
codevs 5963 [SDOI2017]树点染色相关推荐
- codevs 1191 树轴染色 线段树区间定值,求和
codevs 1191 树轴染色 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.codevs.cn/problem/1191/ Des ...
- codevs 1082 线段树区间求和
codevs 1082 线段树练习3 链接:http://codevs.cn/problem/1082/ sumv是维护求和的线段树,addv是标记这歌节点所在区间还需要加上的值. 我的线段树写法在运 ...
- BZOJ 4817: [Sdoi2017]树点涂色
4817: [Sdoi2017]树点涂色 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 273 Solved: 164 [Submit][Stat ...
- [Codevs] 1082 线段树练习3
1082 线段树练习 3 时间限制: 3 s 空间限制: 128000 KB 题目等级 : 大师 Master 题目描述 Description 给你N个数,有两种操作: 1:给区间[a,b]的 ...
- [Bzoj4817] [Sdoi2017]树点涂色 (LCT神题)
4817: [Sdoi2017]树点涂色 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 629 Solved: 371 [Submit][Stat ...
- 线段树区间染色 浮水法 学习小记 Poj 2777 + Poj 2528
复习过的东西必须时常拿来练练,虽说都是水题.... Poj 2777 典型的区间染色问题,貌似我的写法为了不数组越界必须多开一倍的数组空间.....还没有想到解决方法,有机会参考一下别人的写法. Po ...
- POJ2528【线段树经典染色。】
题目链接:http://poj.org/problem?id=2528 来一点转的线段树精髓: 1. 线段树是二叉树,且必定是平衡二叉树,但不一定是完全二叉树. 2. 对于区间[a,b],令mid=( ...
- BZOJ 4817: [Sdoi2017]树点涂色(LCT+树剖+线段树)
题目描述 Bob有一棵 nn 个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同. 定义一条路径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜色. Bob ...
- Bzoj4817:[SDOI2017]树点涂色
题面 Bzoj Sol 做个转化 最开始都是虚边 操作\(1\)就是\(LCT\)里的\(Access\)操作 求的就是路径上虚边的个数+1 然后就好办了 用树链剖分+线段树来维护每个点到根虚边的个数 ...
最新文章
- 0-1背包问题 动态规划java_C#使用动态规划解决0-1背包问题实例分析
- Android设计模式(九)--外观模式
- 程序员面试什么最重要
- python必刷面试_Python面试必刷题系列(5)
- 电路常识性概念(8)-MOS管及简单CMOS逻辑门电路原理图
- 【目标检测_CentripetalNet】CentripetalNet: Pursuing High-quality Keypoint Pairs for Object Detection_2020
- c语言while运行出现错误,【图片】为什么我的while(1)不执行啊?【c语言吧】_百度贴吧...
- php设计是什么意思,php – 什么是更好的设计?
- mysql用户及权限管理_MySQL 用户及权限管理
- JAVA入门级教学之(super的内存示意)
- 胶囊神经网络模型简介_胶囊网络简介
- Ir_scheduler模块
- 阿里云服务器共享型、计算型和通用型有什么区别?
- 通信专业实务(三)——接入网
- 解决Mac book pro (M1芯片)电脑打开idea卡顿,cpu飙升的问题。
- 美元和人民币 货币转换
- ios 自定义键盘的按键音效和震动效果
- 加州理工学院宋飏老师招收机器学习全奖博士生|2023秋季
- JAVA SE之面向对象12:集合3(Set)
- HDU6305: RMQ Similar Sequence 题解