bzoj4551: [Tjoi2016&Heoi2016]树(树链剖分)
4551: [Tjoi2016&Heoi2016]树
题目:传送门
题解:
一道树剖裸题
线段树的c值维护新编号最大的已被标记的节点。
用一个数组转化新编号为旧编号(就是因为这个小细节打错ORZ)
然后就是一顿乱撸
代码:
1 #include<cstdio> 2 #include<cstring> 3 #include<cstdlib> 4 #include<cmath> 5 #include<algorithm> 6 #define N 110000 7 using namespace std; 8 struct node 9 { 10 int x,y,next; 11 }a[N*2];int len,last[N]; 12 void ins(int x,int y) 13 { 14 len++;a[len].x=x;a[len].y=y; 15 a[len].next=last[x];last[x]=len; 16 } 17 struct trnode 18 { 19 int l,r,c,lc,rc; 20 }tr[N*2];int trlen; 21 void bt(int l,int r) 22 { 23 int now=++trlen; 24 tr[now].l=l;tr[now].r=r;tr[now].c=-1; 25 tr[now].lc=tr[now].rc=-1; 26 if(l<r) 27 { 28 int mid=(l+r)/2; 29 tr[now].lc=trlen+1;bt(l,mid); 30 tr[now].rc=trlen+1;bt(mid+1,r); 31 } 32 } 33 int dep[N],tot[N],ys[N],son[N],fa[N],top[N],id[N],z; 34 void pre_tree_node(int x) 35 { 36 tot[x]=1;son[x]=0; 37 for(int k=last[x];k;k=a[k].next) 38 { 39 int y=a[k].y; 40 if(y!=fa[x]) 41 { 42 fa[y]=x; 43 dep[y]=dep[x]+1; 44 pre_tree_node(y); 45 tot[x]+=tot[y]; 46 if(tot[y]>tot[son[x]])son[x]=y; 47 } 48 } 49 } 50 void pre_tree_edge(int x,int tp) 51 { 52 ys[x]=++z;top[x]=tp;id[z]=x; 53 if(son[x]!=0)pre_tree_edge(son[x],tp); 54 for(int k=last[x];k;k=a[k].next) 55 { 56 int y=a[k].y; 57 if(y!=fa[x] && y!=son[x]) 58 pre_tree_edge(y,y); 59 } 60 } 61 void change(int now,int x) 62 { 63 if(tr[now].l==tr[now].r){tr[now].c=x;return ;} 64 int lc=tr[now].lc,rc=tr[now].rc,mid=(tr[now].l+tr[now].r)/2; 65 if(x<=mid)change(lc,x); 66 else change(rc,x); 67 tr[now].c=max(tr[lc].c,tr[rc].c); 68 } 69 int find_x(int now,int l,int r) 70 { 71 if(tr[now].l==l&&tr[now].r==r)return tr[now].c; 72 int lc=tr[now].lc,rc=tr[now].rc,mid=(tr[now].l+tr[now].r)/2; 73 if(r<=mid)return find_x(lc,l,r); 74 else if(l>mid)return find_x(rc,l,r); 75 else return max(find_x(lc,l,mid),find_x(rc,mid+1,r)); 76 } 77 int get_id(int x) 78 { 79 int T=top[x]; 80 while(1) 81 { 82 int k=find_x(1,ys[T],ys[x]); 83 if(k==-1) 84 { 85 x=fa[T]; 86 T=top[x]; 87 } 88 else return id[k]; 89 } 90 } 91 char s[5]; 92 int main() 93 { 94 int n,m; 95 scanf("%d%d",&n,&m); 96 for(int i=1;i<n;i++) 97 { 98 int x,y; 99 scanf("%d%d",&x,&y); 100 ins(x,y); 101 } 102 dep[1]=0;fa[1]=0;pre_tree_node(1);z=0;pre_tree_edge(1,1);trlen=0;bt(1,z);change(1,ys[1]); 103 while(m--) 104 { 105 int x; 106 scanf("%s%d",s+1,&x); 107 if(s[1]=='Q')printf("%d\n",get_id(x)); 108 else change(1,ys[x]); 109 } 110 return 0; 111 }