CF343D Water Tree 树链剖分

问题描述

LG-CF343D


题解

树剖,线段树维护0-1序列

yzhang:用珂朵莉树维护多好


\(\mathrm{Code}\)

#include<bits/stdc++.h>
using namespace std;

template <typename Tp>
void read(Tp &x){
	x=0;char ch=1;int fh;
	while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
	if(ch=='-'){fh=-1;ch=getchar();	}
	else fh=1;
	while(ch>='0'&&ch<='9')	x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
	x*=fh;
}

const int maxn=500007;
const int maxm=1000007;

int n,T;
int Head[maxn],to[maxm],Next[maxm],tot;

void add(int x,int y){
	to[++tot]=y,Next[tot]=Head[x],Head[x]=tot;
}

int size[maxn],son[maxn];
int fa[maxn],dep[maxn],top[maxn],New[maxn],pre[maxn],ind;

void dfs1(int x,int f,int dp){
	size[x]=1,fa[x]=f,dep[x]=dp;
	int mx=-1;
	for(int i=Head[x];i;i=Next[i]){
		int y=to[i];
		if(y==f) continue;
		dfs1(y,x,dp+1);size[x]+=size[y];
		if(size[y]>mx) mx=size[y],son[x]=y;
	}
}

int dfn[maxn];

void dfs2(int x,int tp){
	top[x]=tp,New[x]=++ind,pre[ind]=x,dfn[x]=ind;
	if(!son[x]) return;
	dfs2(son[x],tp);
	for(int i=Head[x];i;i=Next[i]){
		int y=to[i];
		if(y==fa[x]||y==son[x]) continue;
		dfs2(y,y);
	}
	dfn[x]=ind;
}

#define lfc (x<<1)
#define rgc ((x<<1)|1)
#define mid ((l+r)>>1)

int val[maxn<<2],lazy[maxn<<2];

int L,R,need;

void pushdown(int x){
	lazy[lfc]=lazy[rgc]=lazy[x];val[lfc]=val[rgc]=lazy[x]-1;
	lazy[x]=0;
}

void pushup(int x){
	val[x]=val[lfc]+val[rgc];
}

void change(int x,int l,int r){
	if(L>r||R<l) return;
	if(L<=l&&r<=R){
		lazy[x]=need+1,val[x]=need;return;
	}
	if(lazy[x]) pushdown(x);
	change(lfc,l,mid);change(rgc,mid+1,r);
	pushup(x);
}

int query(int x,int l,int r){
	if(l==r) return val[x];
	if(lazy[x]) pushdown(x);
	int res;
	if(L<=mid) res=query(lfc,l,mid);
	else res=query(rgc,mid+1,r);
	pushup(x);
	return res;
}

void cz1(){
	int x;read(x);
	L=New[x],R=dfn[x],need=1;
	change(1,1,n);
}

void cz2(){
	int x,y=1;read(x);
	while(top[x]!=top[y]){
		if(dep[top[x]]<dep[top[y]]) swap(x,y);
		L=New[top[x]],R=New[x],need=0;
		change(1,1,n);
		x=fa[top[x]];
	}
	if(dep[x]>dep[y]) swap(x,y);
	L=New[x],R=New[y],need=0;
	change(1,1,n);
}

void cz3(){
	int x;read(x);
	L=New[x];
	printf("%d\n",query(1,1,n));
}

int main(){
	read(n);
	for(int i=1,x,y;i<n;i++){
		read(x);read(y);
		add(x,y);add(y,x);
	}
	dfs1(1,0,1);dfs2(1,1);
	read(T);int op;
	while(T--){
		read(op);
		if(op==1) cz1();
		else if(op==2) cz2();
		else cz3();
	}
	return 0;
}
posted @ 2019-11-03 21:20  览遍千秋  阅读(183)  评论(0编辑  收藏  举报