zoukankan      html  css  js  c++  java
  • 【BZOJ】1782: [Usaco2010 Feb]slowdown 慢慢游

    【算法】DFS序+树状数组

    【题解】题意相当于统计前i-1个点在第i个点的祖先的个数,显然可以用dfs维护,用树状数组差分维护前缀和。

    出栈不新加节点就要注意左闭右开,即in[a[i]]处+1,ou[a[i]]+1处-1。

    出栈新加节点就要注意数组开双倍

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cctype>
    #define lowbit(x) x&(-x)
    using namespace std;
    const int maxn=100010;
    struct edge{int v,from;}e[maxn*3];
    int first[maxn],in[maxn],ou[maxn],tot=0,cnt=0,b[maxn*2],a[maxn],n;
    
    int read()
    {
        char c;int s=0,t=1;
        while(!isdigit(c=getchar()))if(c=='-')t=-1;
        do{s=s*10+c-'0';}while(isdigit(c=getchar()));
        return s*t;
    }
    void insert(int u,int v){tot++;e[tot].v=v;e[tot].from=first[u];first[u]=tot;}
    void dfs(int x,int fa){
        in[x]=++cnt;
        for(int i=first[x];i;i=e[i].from)if(e[i].v!=fa)dfs(e[i].v,x);
        ou[x]=++cnt;
    }
    void modify(int x,int k){for(int i=x;i<=cnt;i+=lowbit(i))b[i]+=k;}
    int ask(int x){int ans=0;for(int i=x;i>=1;i-=lowbit(i))ans+=b[i];return ans;}
    int main(){
        n=read();
        int u,v;
        for(int i=1;i<n;i++){
            u=read();v=read();
            insert(u,v);
            insert(v,u);
        }
        for(int i=1;i<=n;i++)a[i]=read();
        dfs(1,-1);
        for(int i=1;i<=n;i++){
            printf("%d
    ",ask(in[a[i]]));
            modify(in[a[i]],1);
            modify(ou[a[i]],-1);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    公司真题-字节跳动
    全素组探求
    枚举
    求n个整数的最大公约数
    Ajax技术
    读文本文件
    JSTL标签库
    URL跟URi的区别
    常用的JSTL标签
    EL表达语言
  • 原文地址:https://www.cnblogs.com/onioncyc/p/7456921.html
Copyright © 2011-2022 走看看