bzoj4551: [Tjoi2016&Heoi2016]树
来源:互联网 发布:类似易企秀的软件 编辑:程序博客网 时间:2024/06/04 18:37
链接
http://www.lydsy.com/JudgeOnline/problem.php?id=4551
题解
还行吧这道题,不是特别傻逼。
一个点被标记,显然会影响到子树中的所有点。
显然每次查询会选择这个点到根的路径上深度最深的那个祖先点作为答案。
做法一
离线并查集,ftm用了这种方法,倒序变成删除标记。剩下的细节请读者思考。
做法二
LCT直接暴力,一开始想用这个,但是看到题目下方:新加了九组测试数据,我就知道它想卡这个。弃疗。
做法三
这个算法我感觉长得比较像正解。
算出dfs序,每次修改,就把这个点的子树对这个点的深度取个max。
线段树区间取max,单点查询。
代码
//线段树 #include <cstdio>#include <algorithm>#define maxn 200010using namespace std;int tid[maxn], ltid[maxn], rtid[maxn], untid[maxn], N, Q, nex[maxn], to[maxn], head[maxn], tot, ndtot, deep[maxn];inline void adde(int a, int b){to[++tot]=b;nex[tot]=head[a];head[a]=tot;}struct segtree{int l, r, tag, max; segtree *ch[2];}pool[maxn], *root;inline int read(int x=0){ char c=getchar(); while(c<48 or c>57)c=getchar(); while(c>=48 and c<=57)x=(x<<1)+(x<<3)+c-48, c=getchar(); return x;}inline char readc(){ char c=getchar(); while(c!='Q' and c!='C')c=getchar(); return c;}void dfs(int pos){ int p; ltid[pos]=tid[pos]=++tid[0];untid[tid[pos]]=pos; for(p=head[pos];p;p=nex[p])deep[to[p]]=deep[pos]+1, dfs(to[p]); rtid[pos]=tid[0];}void build(segtree *p, int l, int r){ int mid=(l+r)>>1; p->l=l, p->r=r; if(l==r)return; build(p->ch[0]=pool+ ++ndtot,l,mid); build(p->ch[1]=pool+ ++ndtot,mid+1,r);}void init(){ int a, b, i; N=read(), Q=read(); for(i=1;i<N;i++)a=read(), b=read(), adde(a,b); deep[1]=1, dfs(1); build(root=pool+ ++ndtot,1,N);}inline void u(int a, int &b){if(deep[a]>deep[b])b=a;}inline void tag(segtree *p, int tag){u(tag,p->tag);}inline void pushdown(segtree *p){ u(p->tag,p->max); if(p->ch[0])tag(p->ch[0],p->tag),tag(p->ch[1],p->tag);}inline void update(segtree *p){ if(!p->ch[0])return; pushdown(p->ch[0]), pushdown(p->ch[1]); if(deep[p->ch[0]->max]>deep[p->ch[1]->max])p->max=p->ch[0]->max; else p->max=p->ch[1]->max;}void segchg(segtree *p, int l, int r, int a){ pushdown(p); int mid=(p->l+p->r)>>1; if(l<=p->l and r>=p->r){tag(p,a);return;} if(l<=mid)segchg(p->ch[0],l,r,a); if(r>mid)segchg(p->ch[1],l,r,a); update(p);}int segmax(segtree *p, int l, int r){ pushdown(p); int mid=(p->l+p->r)>>1, ans=0; if(l<=p->l and r>=p->r)return p->max; if(l<=mid)u(segmax(p->ch[0],l,r),ans); if(r>mid)u(segmax(p->ch[1],l,r),ans); return ans;}void work(){ int pos; char type; tag(root,1); while(Q--) { type=readc(); pos=read(); if(type=='C')segchg(root,ltid[pos],rtid[pos],pos); else printf("%d\n",segmax(root,tid[pos],tid[pos])); }}int main(){ init(); work(); return 0;}
0 0
- BZOJ4551 [Tjoi2016&Heoi2016]树
- 【bzoj4551】[Tjoi2016&Heoi2016]树
- bzoj4551【TJOI2016&HEOI2016】树
- BZOJ4551: [Tjoi2016&Heoi2016]树
- bzoj4551: [Tjoi2016&Heoi2016]树
- 【bzoj4551】[Tjoi2016&Heoi2016]树
- 【bzoj4551】【Tjoi2016】【Heoi2016】【树】【线段树】
- 【bzoj4551】【Tjoi2016&Heoi2016】【树】【并查集】
- BZOJ4551——[Tjoi2016&Heoi2016]树
- [BZOJ4551][Tjoi2016&Heoi2016]树 dfs序+线段树
- [BZOJ4551][Tjoi2016&Heoi2016]树(dfs序+线段树)
- [bzoj4551][Tjoi2016&Heoi2016]树 dfs序+线段树
- 【bzoj4551】[Tjoi2016&Heoi2016]树 暴力?树剖+树状数组+二分
- 倍增+树状数组——BZOJ4551 [Tjoi2016&Heoi2016]树
- [bzoj4551][TJOI&HEOI2016]树
- BZOJ4551[HEOI2016]树
- 4551: [Tjoi2016&Heoi2016]树
- [Tjoi2016&Heoi2016]树
- Java之final、finally、finalize
- js获取select标签选中的值
- Codeforces Round #408 (Div. 2) D.Police Stations【Bfs+思维】
- okHttp网络请求框架 get 及post请求方式
- 【Spring学习29】cglib的Lookup方法
- bzoj4551: [Tjoi2016&Heoi2016]树
- AOP的hello world
- leetcode 100. Same Tree
- 1037. 在霍格沃茨找零钱(20)
- atcoder square869120Contest #4 D
- 【深度学习】caffe 中的一些参数介绍
- 林子雨—大数据技术原理与应用—上机实验五
- 序列化语义
- Java序列化与反序列化 & 深拷贝