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;
    }
  • 相关阅读:
    【LeetCode】17. Letter Combinations of a Phone Number
    【LeetCode】16. 3Sum Closest
    【LeetCode】15. 3Sum 三个数和为0
    【LeetCode】14. Longest Common Prefix 最长前缀子串
    【LeetCode】13. Roman to Integer 罗马数字转整数
    【LeetCode】12. Integer to Roman 整型数转罗马数
    【LeetCode】11. Container With Most Water
    【LeetCode】10. Regular Expression Matching
    Models of good programmer
    RSA Algorithm
  • 原文地址:https://www.cnblogs.com/Kv-Stalin/p/8195630.html
Copyright © 2011-2022 走看看