bzoj4817[Sdoi2017]树点涂色
2017-12-27 20:54
381 查看
4817: [Sdoi2017]树点涂色
Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 557 Solved: 326
[Submit][Status][Discuss]
Description
Bob有一棵n个点的有根树,其中1号点是根节点。Bob在每个点上涂了颜色,并且每个点上的颜色不同。定义一条路
径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜色。Bob可能会进行这几种操作:
1 x:
把点x到根节点的路径上所有的点染上一种没有用过的新颜色。
2 x y:
求x到y的路径的权值。
3 x y:
在以x为根的子树中选择一个点,使得这个点到根节点的路径权值最大,求最大权值。
Bob一共会进行m次操作
Input
第一行两个数n,m。
接下来n-1行,每行两个数a,b,表示a与b之间有一条边。
接下来m行,表示操作,格式见题目描述
1<=n,m<=100000
Output
每当出现2,3操作,输出一行。
如果是2操作,输出一个数表示路径的权值
如果是3操作,输出一个数表示权值的最大值
Sample Input
5 6
1 2
2 3
3 4
3 5
2 4 5
3 3
1 4
2 4 5
1 5
2 4 5
Sample Output
3
4
2
2
HINT
LCT中点X的真儿子是−−>ch[x][1/0]所属splay中最左边的点(深度最浅的点)
Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 557 Solved: 326
[Submit][Status][Discuss]
Description
Bob有一棵n个点的有根树,其中1号点是根节点。Bob在每个点上涂了颜色,并且每个点上的颜色不同。定义一条路
径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜色。Bob可能会进行这几种操作:
1 x:
把点x到根节点的路径上所有的点染上一种没有用过的新颜色。
2 x y:
求x到y的路径的权值。
3 x y:
在以x为根的子树中选择一个点,使得这个点到根节点的路径权值最大,求最大权值。
Bob一共会进行m次操作
Input
第一行两个数n,m。
接下来n-1行,每行两个数a,b,表示a与b之间有一条边。
接下来m行,表示操作,格式见题目描述
1<=n,m<=100000
Output
每当出现2,3操作,输出一行。
如果是2操作,输出一个数表示路径的权值
如果是3操作,输出一个数表示权值的最大值
Sample Input
5 6
1 2
2 3
3 4
3 5
2 4 5
3 3
1 4
2 4 5
1 5
2 4 5
Sample Output
3
4
2
2
HINT
LCT中点X的真儿子是−−>ch[x][1/0]所属splay中最左边的点(深度最浅的点)
#include<iostream> #include<cstdio> using namespace std; int num,id; #define N 105000 int vet[N*2],Next[N*2]; int dep ,hed ,IN ,OUT ,F [20]; int ch [2],f ,haha ; int Ma[N*4],tag[N*4]; void add(int u,int v){ ++num; vet[num]=v; Next[num]=hed[u]; hed[u]=num; } void dfs(int u,int fa){ F[u][0]=fa; f[u]=fa; dep[u]=dep[fa]+1; IN[u]=++id; haha[id]=u; for (int i=hed[u];i!=-1;i=Next[i]){ int v=vet[i]; if (v==fa) continue; dfs(v,u); } OUT[u]=id; } void update(int p){ Ma[p]=max(Ma[p<<1],Ma[p<<1|1]); } void pushdown(int p){ if (tag[p]){ Ma[p<<1]+=tag[p]; tag[p<<1]+=tag[p]; Ma[p<<1|1]+=tag[p]; tag[p<<1|1]+=tag[p]; tag[p]=0; } } void build(int p,int l,int r){ if (l==r){ Ma[p]=dep[haha[l]]; //cout<<p<<" "<<Ma[p]<<endl; tag[p]=0; return; } int mid=(l+r)>>1; build(p<<1,l,mid); build(p<<1|1,mid+1,r); update(p); } void insert(int p,int l,int r,int x,int y,int z){ if (l==x&&r==y){ Ma[p]+=z; tag[p]+=z; return; } pushdown(p); int mid=(l+r)>>1; if (y<=mid) insert(p<<1,l,mid,x,y,z); else if (x>=mid+1) insert(p<<1|1,mid+1,r,x,y,z); else{ insert(p<<1,l,mid,x,mid,z); insert(p<<1|1,mid+1,r,mid+1,y,z); } update(p); } int query(int p,int l,int r,int x,int y){ //cout<<Ma[p]<<" "<<l<<" "<<r<<endl; if (l==x&&r==y) return Ma[p]; pushdown(p); int mid=(l+r)>>1; if (y<=mid) return query(p<<1,l,mid,x,y); if (x>=mid+1) return query(p<<1|1,mid+1,r,x,y); return max(query(p<<1,l,mid,x,mid),query(p<<1|1,mid+1,r,mid+1,y)); } bool isroot(int x){ return (ch[f[x]][1]!=x&&ch[f[x]][0]!=x); } void rotate(int x){ int y=f[x],z=f[y]; int l=(ch[y][1]==x),r=l^1; if (!isroot(y)) ch[z][ch[z][1]==y]=x; f[x]=z;f[y]=x;f[ch[x][r]]=y; ch[y][l]=ch[x][r];ch[x][r]=y; } void splay(int x){ while (!isroot(x)){ int y=f[x],z=f[y]; if (!isroot(y)){ if (ch[y][0]==x^ch[z][0]==y) rotate(x); else rotate(y); } rotate(x); } } void access(int x){ int y=0; while (x){ splay(x); if (ch[x][1]){ int xx=ch[x][1]; while (ch[xx][0]) xx=ch[xx][0]; insert(1,1,id,IN[xx],OUT[xx],1); } if (y){ int xx=y; while (ch[xx][0]) xx=ch[xx][0]; insert(1,1,id,IN[xx],OUT[xx],-1); } ch[x][1]=y; y=x;x=f[x]; } } int lca(int u,int v){ if (dep[u]<dep[v]) swap(u,v); for (int i=17;i>=0;--i) if (dep[F[u][i]]>=dep[v]) u=F[u][i]; if (u==v) return u; for (int i=17;i>=0;--i) if (F[u][i]!=F[v][i]) u=F[u][i],v=F[v][i]; return F[u][0]; } int get_sum(int x){ int ans=0; while (x){ splay(x); x=f[x]; ++ans; } return ans; } int main(){ int n,m; scanf("%d%d",&n,&m); for (int i=1;i<=n;++i) hed[i]=-1; for (int i=1;i<n;++i){ int u,v; scanf("%d%d",&u,&v); add(u,v); add(v,u); } id=0; dep[0]=0; dfs(1,0); for (int j=1;j<=17;++j) for (int i=1;i<=n;++i) F[i][j]=F[F[i][j-1]][j-1]; build(1,1,id); while (m--){ int opt,x; scanf("%d%d",&opt,&x); if (opt==1) access(x); if (opt==2){ int y; scanf("%d",&y); int z=lca(x,y); //cout<<get_sum(x)<<" "<<get_sum(y)<<" "<<get_sum(z)<<endl; printf("%d\n",get_sum(x)+get_sum(y)-(get_sum(z)<<1)+1); } if (opt==3){ //cout<<IN[x]<<" "<<OUT[x]<<endl; printf("%d\n",query(1,1,id,IN[x],OUT[x])); } } return 0; }
相关文章推荐
- BZOJ.4817.[SDOI2017]树点涂色(LCT DFS序 线段树)
- bzoj 4817: [Sdoi2017]树点涂色
- bzoj 4817: [Sdoi2017]树点涂色
- bzoj4817: [Sdoi2017]树点涂色
- [SDOI2017][bzoj4817] 树点涂色 [LCT+线段树]
- AC日记——[SDOI2017]树点涂色 bzoj 4817
- bzoj 4817: [Sdoi2017]树点涂色 link cut tree+线段树+树链剖分
- [BZOJ]4817: [Sdoi2017]树点涂色
- BZOJ 4817: [Sdoi2017]树点涂色
- bzoj 4817: [Sdoi2017]树点涂色 LCT+树链剖分+线段树
- BZOJ 4817: [Sdoi2017]树点涂色(LCT+树剖+线段树)
- [LCT] BZOJ4817.[Sdoi2017]树点涂色
- bzoj 4817: [Sdoi2017]树点涂色【树链剖分+LCT】
- 【BZOJ4817】【SDOI2017】树点涂色 [LCT][线段树]
- BZOJ4817 [Sdoi2017]树点涂色(洛谷P3703)
- BZOJ 4817 [Sdoi2017]树点涂色 ——LCT 线段树
- [BZOJ4817][SDOI2017]树点涂色(LCT+线段树+差分)
- [BZOJ4817][SDOI2017]树点涂色(DFS序+LCA+树剖+LCT)
- bzoj4817 [Sdoi2017]树点涂色
- [BZOJ4817]树点涂色