zoukankan      html  css  js  c++  java
  • 洛谷 P3258 [JLOI2014]松鼠的新家

    树剖,裸题,鉴定完毕。

    我是题面

    读完题,恩,树剖,裸题,没劲。

    处理很简单,既然每到一个房间吃一块糖,那么就在每条路径上的每个房间放一颗糖,但是每条路径的终点也就是下一条路径的起点,在这里只能加一次,所以别忘记处理完再-1,又因为最后一个点不需要糖,所以直接每条路径的终点的糖-1即可

    上代码

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cctype>
    #define ll long long
    #define gc() getchar()
    #define maxn 300005
    using namespace std;
    
    inline ll read(){
    	ll a=0;int f=0;char p=gc();
    	while(!isdigit(p)){f|=p=='-';p=gc();}
    	while(isdigit(p)){a=(a<<3)+(a<<1)+(p^48);p=gc();}
    	return f?-a:a;
    }
    void write(ll a){
    	if(a>9)write(a/10);
    	putchar(a%10+'0');
    }
    int n,m,a[maxn];
    
    int tot,head[maxn];
    struct ahaha1{
    	int to,next;
    }e[maxn<<1];
    inline void add(int u,int v){
    	e[tot].to=v;e[tot].next=head[u];head[u]=tot++;
    }
    
    int sz[maxn],dep[maxn],son[maxn],f[maxn];
    void dfs(int u,int fa){
    	int maxa=0;sz[u]=1;
    	for(int i=head[u];~i;i=e[i].next){
    		int v=e[i].to;if(v==fa)continue;
    		f[v]=u;dep[v]=dep[u]+1;
    		dfs(v,u);sz[u]+=sz[v];
    		if(maxa<sz[v])maxa=sz[v],son[u]=v;
    	}
    }
    int top[maxn],in[maxn],b[maxn];
    void dfs(int u,int fa,int topf){
    	top[u]=topf;in[u]=++tot;b[tot]=u;
    	if(!son[u])return;
    	dfs(son[u],u,topf);
    	for(int i=head[u];~i;i=e[i].next){
    		int v=e[i].to;if(v==fa||v==son[u])continue;
    		dfs(v,u,v);
    	}
    }
    
    #define lc p<<1
    #define rc p<<1|1
    struct ahaha2{
    	ll v,lz;
    }t[maxn<<2];
    inline void pushup(int p){
    	t[p].v=t[lc].v+t[rc].v;
    }
    inline void pushdown(int p,int l,int r){
    	int m=l+r>>1;
    	t[lc].v+=t[p].lz*(m-l+1);t[lc].lz+=t[p].lz;
    	t[rc].v+=t[p].lz*(r-m);t[rc].lz+=t[p].lz;
    	t[p].lz=0;
    }
    void update(int p,int l,int r,int L,int R){
    	if(l>R||r<L)return;
    	if(L<=l&&r<=R){t[p].v+=r-l+1;t[p].lz++;return;}
    	int m=l+r>>1;if(t[p].lz)pushdown(p,l,r);
    	update(lc,l,m,L,R);update(rc,m+1,r,L,R);
    	pushup(p);
    }
    void update2(int p,int l,int r,int L){
    	if(l==r){t[p].v--;return;}
    	int m=l+r>>1;if(t[p].lz)pushdown(p,l,r);
    	if(m>=L)update2(lc,l,m,L);
    	else update2(rc,m+1,r,L);
    	pushup(p);
    }
    ll query(int p,int l,int r,int L){
    	if(l==r)return t[p].v;
    	int m=l+r>>1;if(t[p].lz)pushdown(p,l,r);
    	if(m>=L)return query(lc,l,m,L);
    	else return query(rc,m+1,r,L);
    }
    
    inline void solve_1(int x,int y){
    	while(top[x]!=top[y]){
    		if(dep[top[x]]<dep[top[y]])swap(x,y);
    		update(1,1,n,in[top[x]],in[x]);
    		x=f[top[x]];
    	}
    	if(dep[x]>dep[y])swap(x,y);
    	update(1,1,n,in[x],in[y]);
    }
    
    int main(){memset(head,-1,sizeof head);
    	n=read();
    	for(int i=1;i<=n;++i)a[i]=read();
    	for(int i=1;i<n;++i){
    		int x=read(),y=read();
    		add(x,y);add(y,x);
    	}
    	tot=0;dfs(1,-1);dfs(1,-1,1);
    	for(int i=2;i<=n;++i)
    		solve_1(a[i-1],a[i]),update2(1,1,n,in[a[i]]);
    	for(int i=1;i<=n;++i)
    		write(query(1,1,n,in[i])),putchar('
    ');
    	return 0;
    }
    
  • 相关阅读:
    词向量的发展
    拉格朗日对偶理解
    EM算法理解
    Xgboost理解
    GBDT理解
    深入理解KS
    PCA主成分分析理解
    SVM理解
    Python调用C++
    Linux opencv安装与编译
  • 原文地址:https://www.cnblogs.com/hanruyun/p/9285998.html
Copyright © 2011-2022 走看看