• 【题解】P3258松鼠的新家


    【题解】[P3258 JLOI2014]松鼠的新家

    树链剖分板子题。

    总结一点容易写错的地方吧:

    • if(d[top[u]]<d[top[v]]) swap(u,v);注意是(top)
    • (dfs2)中,if(e[t].to!=r[now]&&e[t].to!=son[now])注意(r[now])而不是(last)
    #include<bits/stdc++.h>
    
    using namespace std;
    #define RP(t,a,b) for(register int t=(a),edd=(b);t<=edd;++t)
    #define DRP(t,a,b) for(register int t=(a),edd=(b);t>=edd;--t)
    #define ERP(t,a) for(register int t=head[a];t;t=e[t].nx)
    #define Max(a,b) ((a)<(b)?(b):(a))
    #define Min(a,b) ((a)<(b)?(a):(b))
    #define midd register int mid=(l+r)>>1
    #define TMP template < class ccf >
    #define lowbit(x) ((x)&(-(x)))
    
    TMP inline ccf qr(ccf b){
        char c=getchar();
        int q=1;
        ccf x=0;
        while(c<48||c>57)
    	q=c==45?-1:q,c=getchar();
        while(c>=48&&c<=57)
    	x=x*10+c-48,c=getchar();
        return q==-1?-x:x;
    }
    const int maxn=300005;
    struct E{
        int to,nx;
    }e[maxn<<1];
    int cnt,n;
    int head[maxn];
    int mov[maxn];
    int toseg[maxn];
    int siz[maxn];
    int son[maxn];
    int top[maxn];
    int r[maxn];
    int d[maxn];
    int seg[maxn];
    
    inline void add(int to,int fr,bool f){
        e[++cnt]=(E){to,head[fr]};
        head[fr]=cnt;
        if(f)
    	add(fr,to,0);
    }
    
    void dfs1(int now,int last){
        d[now]=d[last]+1;
        r[now]=last;
        siz[now]=1;
        ERP(t,now){
    	if(e[t].to!=last){
    	    dfs1(e[t].to,now);
    	    siz[now]+=siz[e[t].to];
    	    if(siz[e[t].to]>siz[son[now]])
    		son[now]=e[t].to;
    	}
        }
    }
    
    void dfs2(int now,int last){
    
        top[now]=last;
        toseg[now]=++toseg[0];
        if(son[now])
    	dfs2(son[now],last);
        ERP(t,now)
    	if(e[t].to!=r[now]&&e[t].to!=son[now])
    	    dfs2(e[t].to,e[t].to);
    
    }
    
    inline void basic_add(int x,int tag){
        for(register int t=x;t<=n;t+=lowbit(t))seg[t]+=tag;
    }
    
    inline void inv_add(int l,int r,int tag){
        basic_add(l,tag);basic_add(r+1,-tag);
    }
    
    inline void upd(int u,int v){
        while(top[u]!=top[v]){
    	if(d[top[u]]<d[top[v]]) swap(u,v);
    	inv_add(toseg[top[u]],toseg[u],1);
    	u=r[top[u]];
        }
        if(d[u]<d[v]) swap(u,v);
        inv_add(toseg[v],toseg[u],1);
    }
    
    int main(){
    #ifndef ONLINE_JUDGE
        freopen("in.in","r",stdin);
        freopen("out.out","w",stdout);
    #endif
        n=qr(1);
        RP(t,1,n) mov[t]=qr(1);
        for(register int t=2,t1,t2;t<=n;++t)
    	t1=qr(1),t2=qr(1),add(t1,t2,1);
        dfs1(1,0);
        dfs2(1,1);
        
        RP(t,1,n-1)
    	upd(mov[t],mov[t+1]);
        
        RP(t,2,n)
    	inv_add(toseg[mov[t]],toseg[mov[t]],-1);
        RP(t,1,n){
    	register int ans=0;
    	for(register int i=toseg[t];i;i-=lowbit(i))
    	    ans+=seg[i];
    	printf("%d
    ",ans);
        }
        return 0;
    }
    
    
  • 相关阅读:
    常用排序算法--合并排序和快速排序
    常用排序算法--冒泡排序及改进和插入排序时间复杂度分析
    常用数据结构图--拓扑排序
    常用数据结构栈的应用—-表达式求值
    Session原理,生命周期
    jsp内置对象out 和response.getwriter().write()的区别
    div中的div在父容器中水平居中或者垂直居中
    <!DOCTYPE html> 到底是什么意思?
    设置了环境变量,为什么执行javac报找不到javac: 找不到文件
    自动抽取邮件内容
  • 原文地址:https://www.cnblogs.com/winlere/p/10357808.html
Copyright © 2020-2023  润新知