省选专练之数据结构[JLOI2014]松鼠的新家

简单的树链剖分

主要是为了复习

利用线段树维护区间加1就好了

// ConsoleApplication5.cpp: 定义控制台应用程序的入口点。
//

//#include "stdafx.h"
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#define lc (p<<1)
#define rc (p<<1|1)
using namespace std;
inline void read(int &x){
	x=0;
	int 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();
	}
	x*=f;
}
const int N = 1e6;
struct Front_star {
    int u, v, nxt;
}e[N*4];
int first[N] = {};
int cnt = 1;
void add(int u, int v) {
    cnt++;
    e[cnt].u = u;
    e[cnt].v = v;
    e[cnt].nxt = first[u];
    first[u] = cnt;
}
//
int dep[N] = {};
int siz[N] = {};
int son[N] = {};
int fa[N] = {};
int top[N] = {};
int tree[N] = {};
int pre[N] = {};
int tot = 0;
void dfs1(int x, int fat, int depth) {
    fa[x] = fat;
    dep[x] = depth;
    siz[x] = 1;
    for (int i = first[x]; i; i = e[i].nxt) {
        int v = e[i].v;
        if(v==fat)continue;
        dfs1(v, x, depth + 1);
        if (!son[x] || siz[son[x]] < siz[v]) {
            son[x] = v;
        }
    }
}
void dfs2(int x, int tp) {
	tree[x]=++tot;
	pre[tp]=x;
	top[x]=tp;
	if(!son[x])return;
	dfs2(son[x],tp);
	for(int i=first[x];i;i=e[i].nxt){
		int v=e[i].v;
		if(v==fa[x])continue;
		if(v==son[x])continue;
		dfs2(v,v);
	}
}
//
struct Segment_Tree{
	int sum,lson,rson,lazy;
}T[N*4];
inline void PushUp(int p){
	T[p].sum=T[lc].sum+T[rc].sum;
}
inline void PushDown(int p){
	if(T[p].lazy){
//		cout<<p<<" down"<<lc<<" "<<rc<<'\n';
		T[lc].sum+=(T[lc].rson-T[lc].lson+1)*T[p].lazy;
		T[rc].sum+=(T[rc].rson-T[rc].lson+1)*T[p].lazy;
		T[lc].lazy+=T[p].lazy;
		T[rc].lazy+=T[p].lazy;
		T[p].lazy=0;
	}
}
void build(int p,int l,int r){
	T[p].lson=l;
	T[p].rson=r;
	if(l==r){
		T[p].sum=0;
		return;
	}
	int mid=(l+r)/2;
	build(lc,l,mid);
	build(rc,mid+1,r);
	PushUp(p);
}
inline void update(int p,int l,int r,int val){
	if(l<=T[p].lson&&T[p].rson<=r){
//		cout<<"p= "<<p<<'\n';
		T[p].sum+=(T[p].rson-T[p].lson+1)*val;
		T[p].lazy+=val;
		return;
	}
	PushDown(p);
	int mid=(T[p].lson+T[p].rson)/2;
	if(l<=mid)update(lc,l,r,val);
	if(mid<r) update(rc,l,r,val);
	PushUp(p);
}
inline int Query(int p,int l,int r){
//	cout<<p<<" "<<T[p].lson<<" "<<T[p].rson<<'\n';
	if(l<=T[p].lson&&T[p].rson<=r){
		return T[p].sum;
	}
	PushDown(p);
	int mid=(T[p].lson+T[p].rson)/2;
	int ret=0;
	if(l<=mid)ret+=Query(lc,l,r);
	if(r>mid) ret+=Query(rc,l,r);
	return ret;
}
int Up(int x,int y,int val){
	while(top[x]!=top[y]){
		if(dep[top[x]]<dep[top[y]]){
			swap(x,y);
		}
//		cout<<"Up "<<top[x]<<" "<<x<<'\n';
		update(1,tree[top[x]],tree[x],val);
		x=fa[top[x]];
	}
	if(dep[x]>dep[y]){
		swap(x,y);
	}
//	cout<<"Up "<<x<<" "<<y<<'\n';
	update(1,tree[x],tree[y],val);
}
int n;
int a[N]={};
int main(){
//	freopen("P3258.in","r",stdin);
//	scanf("%d",&n);
	read(n);
//	cout<<n;
	for(int i=1;i<=n;i++){
		read(a[i]);
//		scanf("%d",&a[i]);
	}
	for(int i=1;i<n;i++){
		int u,v;
		read(u);
		read(v);
//		scanf("%d%d",&u,&v);
		add(u,v);
		add(v,u);
	}
	dfs1(1,0,1);
//	cout<<"------"<<'\n';
	dfs2(1,1);
	build(1,1,n);
//	Up(a[1],a[2],1);
//	cout<<Query(1,tree[4],tree[4])<<'\n';
//	cout<<T[15].lson<<" "<<T[15].rson<<'\n';
	for(int i=1;i<n;i++){
		Up(a[i],a[i+1],1);
		Up(a[i],a[i],-1);
//		cout<<Query(1,tree[a[i]],tree[a[i]])<<'\n';
	}
	for(int i=1;i<=n;i++){
		int ans=Query(1,tree[i],tree[i]);
		if(a[1]==i)ans++;
		if(a[n]==i)ans--;
		cout<<ans<<'\n';
	}
    return 0;
}


猜你喜欢

转载自blog.csdn.net/fcb_x/article/details/81053542