zoukankan      html  css  js  c++  java
  • P3285 松鼠的新家 (树链剖分)

    题目描述

    松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的。天哪,他居然真的住在”树“上。

    松鼠想邀请****前来参观,并且还指定一份参观指南,他希望**能够按照他的指南顺序,先去a1,再去a2,......,最后到an,去参观新家。可是这样会导致**重复走很多房间,懒惰的**不停地推辞。可是松鼠告诉他,每走到一个房间,他就可以从房间拿一块糖果吃。

    **是个馋家伙,立马就答应了。现在松鼠希望知道为了保证**有糖果吃,他需要在每一个房间各放至少多少个糖果。

    因为松鼠参观指南上的最后一个房间an是餐厅,餐厅里他准备了丰盛的大餐,所以当**在参观的最后到达餐厅时就不需要再拿糖果吃了。

    输入输出格式

    输入格式:

    第一行一个整数n,表示房间个数第二行n个整数,依次描述a1-an接下来n-1行,每行两个整数x,y,表示标号x和y的两个房间之间有树枝相连。

    输出格式: 

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

    输入输出样例

    输入样例#1: 
    5
    1 4 5 3 2
    1 2
    2 4
    2 3
    4 5
    输出样例#1: 
    1
    2
    1
    2
    1

    说明

    2<= n <=300000

    因为这个题,只要最后面查询,所以可以用树状数组的区间修改来做,所以,上代码:

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<cstdio>
    #include<ctime>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<map>
    #include<set>
    #define ll(x) (x*2)
    #define rr(x) (x*2+1)
    #define lol long long 
    using namespace std;
    const int maxn=300008;
    
    lol read()
    {
        char ch=getchar();lol f=1,w=0;
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch<='9'&&ch>='0'){w=w*10+ch-'0';ch=getchar();}
        return f*w;
    }
    
    struct sj{
        lol to;
        lol next;
    }a[maxn*2];
    lol head[maxn],size;
    lol vis[maxn],js[maxn],n;
    lol top[maxn],son[maxn],num[maxn];
    lol id[maxn],dep[maxn],fa[maxn];
    lol c[maxn],nat[maxn];
    
    void add(lol x,lol y)
    {
        a[++size].to=y;
        a[size].next=head[x];
        head[x]=size;
    }
        
    void dfs(lol rt,lol pre,lol deep)
    {
        dep[rt]=deep;
        num[rt]=1;
        fa[rt]=pre;
        for(int i=head[rt];i;i=a[i].next)
        {
            lol tt=a[i].to;
            if(tt!=fa[rt])
            {
                dfs(tt,rt,deep+1);
                num[rt]+=num[tt];
                if(num[tt]>num[son[rt]])
                son[rt]=tt;
            }
        }
    }
    
    int dfn;    
    void dfs_find(lol rt,lol zu)
    {
        dfn++;
        top[rt]=zu; 
        id[rt]=dfn;
        if(son[rt]!=-1) 
        dfs_find(son[rt],zu);
        for(int i=head[rt];i;i=a[i].next)
        {
            lol tt=a[i].to;
            if(tt!=son[rt]&&tt!=fa[rt])
            {
                dfs_find(tt,tt);
            }
        }
        return;
    }    
    
    int lowbit(int x)
    {
        return x&(-x);
    }
    
    void insert(int x,int z)
    {
        for(int i=x;i<=n;i+=lowbit(i))
        {if(i==0)break;c[i]+=z;}
    }
    
    int check(int x)
    {
        int sum=0;
        for(int i=x;i>=1;i-=lowbit(i))
        {
          sum+=c[i];
        }
        return sum;
    }    
    
    void change(int s,int t)                                            //change 还有一点*问题 没有剪掉起点
    {    
        while(top[s]!=top[t])
        {
            if(dep[top[s]]<dep[top[t]])
            swap(s,t);
            insert(id[top[s]],1);
            insert(id[s]+1,-1);
            s=fa[top[s]];
        }
        if(id[s]>id[t])
        swap(s,t);
        insert(id[s],1);
        insert(id[t]+1,-1);
        return;
    }
        
    int main()
    {
        memset(son,-1,sizeof(son));
        memset(top,-1,sizeof(top));
        n=read();
        for(int i=1;i<=n;i++)
        vis[i]=read();
        for(int i=1;i<n;i++)
        {
            lol x,y;
            x=read(); y=read();
            add(x,y); add(y,x);
        }
        dfs(1,0,1); dfs_find(1,1); 
        js[vis[1]]+=1; js[vis[n]]-=1;
        for(int i=1;i<n;i++)
        {
            change(vis[i],vis[i+1]);
            js[vis[i]]-=1;
        }
        for(int i=1;i<=n;i++)
        {
            lol ss;
            ss=check(id[i]);
            ss+=js[i];
            cout<<ss<<endl;
        }
        return 0;
    }
  • 相关阅读:
    深入浅出WPF之Binding的使用(二)
    深入浅出WPF之Binding的使用(一)
    C#中XML的读取
    DependencyProperty属性介绍
    System.Windows.Markup.IQueryAmbient 在未被应用的程序集中定义
    Unity调用windows系统dialog 选择文件夹
    #if
    协程
    将[-1,1]映射到[0,1]
    Editor模式下实例化Prefab
  • 原文地址:https://www.cnblogs.com/Kv-Stalin/p/8195630.html
Copyright © 2011-2022 走看看