• 【bzoj3631】【JLOI2014】松鼠的新家


    题目描述

    松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的。天哪,他居然真的住在“树”上。松鼠想邀请****前来参观,并且还指定一份参观指南,他希望**能够按照他的指南顺序,先去a1,再去a2,……,最后到an,去参观新家。
    可是这样会导致**重复走很多房间,懒惰的**不听地推辞。可是松鼠告诉他,每走到一个房间,他就可以从房间拿一块糖果吃。**是个馋家伙,立马就答应了。
    现在松鼠希望知道为了保证**有糖果吃,他需要在每一个房间各放至少多少个糖果。因为松鼠参观指南上的最后一个房间an是餐厅,餐厅里他准备了丰盛的大餐,所以当**在参观的最后到达餐厅时就不需要再拿糖果吃了。


    输入

    第一行一个整数n,表示房间个数第二行n个整数,依次描述a1-an

    接下来n-1行,每行两个整数x,y,表示标号x和y的两个房间之间有树枝相连。


    输出

    一共n行,第i行输出标号为i的房间至少需要放多少个糖果,才能让**有糖果吃。


    样例输入

    5
    1 4 5 3 2
    1 2
    2 4
    2 3
    4 5


    样例输出

    1
    2
    1
    2
    1


    题解

    a[ i ] 到 a[ i+1 ]之间的点+1,a[ i+1 ]再-1,然后查询所有点就ok。

    #include<cmath>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define ll long long
    
    const int maxn=300000+50;
    const int maxm=600000+50;
    
    int n,fa[maxn],m,cnt,a[maxn];
    int fir[maxn],nex[maxm],to[maxm],ecnt;
    int top[maxn],son[maxn],dep[maxn],sz[maxn],id[maxn];
    
    struct SegmentTree{int v,l,r,add;}st[maxn<<2];
    
    void add(int u,int v){
        nex[++ecnt]=fir[u];fir[u]=ecnt;to[ecnt]=v;
    }
    
    void dfs1(int x,int f,int deep){
        fa[x]=f;dep[x]=deep;
        sz[x]=1;
        for(int e=fir[x];e;e=nex[e]){
            int v=to[e];
            if(v==f) continue;
            dfs1(v,x,deep+1);
            sz[x]+=sz[v];
            if(sz[v]>sz[son[x]]) son[x]=v;
        }
    }
    
    void dfs2(int x,int topf){
        top[x]=topf;
        id[x]=++cnt;
        if(!son[x]) return ;
        dfs2(son[x],topf);
        for(int e=fir[x];e;e=nex[e]){
            int v=to[e];
            if(v==fa[x]||v==son[x]) continue;
            dfs2(v,v);
        }
    }
    
    void pushup(int root){
        st[root].v=st[root<<1].v+st[root<<1|1].v;
    }
    
    void build(int root,int l,int r){
        st[root].l=l;st[root].r=r;
        if(l==r) return ;
        int m=l+r>>1;
        build(root<<1,l,m);build(root<<1|1,m+1,r);
        pushup(root);
    }
    
    void pushdown(int root){
        st[root<<1].v=st[root<<1].v+st[root].add*(st[root<<1].r-st[root<<1].l+1);
        st[root<<1|1].v=st[root<<1|1].v+st[root].add*(st[root<<1|1].r-st[root<<1|1].l+1);
        st[root<<1].add=st[root<<1].add+st[root].add;
        st[root<<1|1].add=st[root<<1|1].add+st[root].add;
        st[root].add=0;
    }
    
    void add(int root,int l,int r,int val){
        if(st[root].l>r||st[root].r<l) return ;
        if(st[root].l>=l&&st[root].r<=r){
            st[root].v=st[root].v+val*(st[root].r-st[root].l+1);
            st[root].add=st[root].add+val;
        }
        else{
            pushdown(root);
            add(root<<1,l,r,val);add(root<<1|1,l,r,val);
            pushup(root);
        }
    }
    
    int query(int root,int l,int r){
        if(st[root].l>r||st[root].r<l) return 0;
        if(st[root].l>=l&&st[root].r<=r) return st[root].v;
        pushdown(root);
        return query(root<<1,l,r)+query(root<<1|1,l,r);
    }
    
    void change(int x,int y,int val){
        int f1=top[x],f2=top[y];
        while(f1!=f2){
            if(dep[f1]<dep[f2]) swap(x,y),swap(f1,f2);
            add(1,id[f1],id[x],val);
            x=fa[f1],f1=top[x];
        }
        if(dep[x]>dep[y]) swap(x,y);
        add(1,id[x],id[y],val);
    }
    
    template<typename T>void read(T& aa){
        char cc; ll ff;aa=0;cc=getchar();ff=1;
        while((cc<'0'||cc>'9')&&cc!='-') cc=getchar();
        if(cc=='-') ff=-1,cc=getchar();
        while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
        aa*=ff;
    }
    
    int main(){
        read(n);
        for(int i=1;i<=n;i++) read(a[i]);
        for(int i=1;i<n;i++){
            int x,y;
            read(x),read(y);
            add(x,y);add(y,x);
        }
        dfs1(1,0,1);dfs2(1,1);build(1,1,n);
        for(int i=1;i<n;i++){
            change(a[i],a[i+1],1);
            change(a[i+1],a[i+1],-1);
        }
        for(int i=1;i<=n;i++) printf("%d
    ",query(1,id[i],id[i]));
        return 0;
    }
  • 相关阅读:
    trie树
    基数排序
    CF724E Goods transportation 最小割 DP
    [CQOI2009]跳舞 网络流
    NOIP2018爆零记
    斜率优化
    CF311B Cats Transport 斜率优化DP
    逆元
    卡特兰数
    【BZOJ】【1565】【NOI2009】PVZ 植物大战僵尸
  • 原文地址:https://www.cnblogs.com/rlddd/p/9806235.html
Copyright © 2020-2023  润新知