• 【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
  • 相关阅读:
    Java线程:线程栈模型与线程的变量
    Java线程:创建与启动
    Java线程:概念与原理
    oracle的备份与恢复
    oracle视图
    oracle PL/SQL的介绍
    Oracle掌管权限和角色
    oracle基础 管理索引
    oracle维护数据的完整性
    删除VisualStudio 2013中的 "send Feedback" 按钮
  • 原文地址:https://www.cnblogs.com/onioncyc/p/7456921.html
Copyright © 2020-2023  润新知