• Count on a tree


    题目链接:https://www.spoj.com/problems/COT/en/

    题意:给你一颗数,树上每个节点都要一个权值,问你u,v结点这条路径上第k大是多少。

    思路:先建立主席树,可知儿子的主席树是由fa数组得到的,并且要更新。

    #include<algorithm>
    #include<cstdio>
    #include<iostream>
    #include<vector>
    #include<cstring>
    #include<map>
    #include<queue>
    #include<cmath>
    using namespace std;
    #define ll long long int
    vector<int> Graph[100005];
    int root[100005],top,sum[8000005];
    int lson[8000005],rson[8000005];
    int a[100005],b[100005],num[100005],n,m;
    int len,d[100005];
    int f[100005][25],t;
    void bfs()
    {
        queue<int>q;
        q.push(1);
        d[1]=1;
        while(q.size())
        {
            int x=q.front();
            q.pop();
            for(int i=0;i<Graph[x].size();i++)
            {
                int y=Graph[x][i];
                if(x==y||d[y])
                    continue;
                d[y]=d[x]+1;
                f[y][0]=x;
                for(int j=1;j<=t;j++)
                    f[y][j]=f[f[y][j-1]][j-1];
                q.push(y);
            }
        }
    }
    int lca(int x,int y)
    {
        if(d[x]>d[y])
            swap(x,y);
        for(int i=t;i>=0;i--)
            if(d[f[y][i]]>= d[x])
                y=f[y][i];
        if(x==y)
            return x;
        for(int i=t;i>=0;i--)
            if(f[x][i]!=f[y][i])
                x=f[x][i],y=f[y][i];
        return f[x][0];
    }
    void Build(int &rt,int l,int r)
    {
        rt=++top;
        lson[rt]=0;
        rson[rt]=0;
        sum[rt]=0;
        if(l==r)
            return;
        int mid=(l+r)>>1;
        Build(lson[rt],l,mid);
        Build(rson[rt],mid+1,r);
    }
    void Update(int &ne,int last,int l,int r,int pos)
    {
        ne=++top;
        sum[ne]=sum[last]+1;
        lson[ne]=lson[last];
        rson[ne]=rson[last];
        if(l==r)
            return;
        int mid=(l+r)>>1;
        if(pos<=mid)
            Update(lson[ne],lson[last],l,mid,pos);
        else
            Update(rson[ne],rson[last],mid+1,r,pos);
    }
    void dfs(int x,int fa)
    {
        Update(root[x],root[fa],1,len,num[x]);
        for(int i=0;i<Graph[x].size();i++)
        {
            int y=Graph[x][i];
            if(y==fa)
                continue;
            dfs(y,x);
        }
    }
    int Query(int x,int y,int f,int fa,int k,int l,int r)
    {
        if(l==r)
            return l;
        int ans=sum[lson[x]]+sum[lson[y]]-sum[lson[f]]-sum[lson[fa]];
        int mid=(l+r)>>1;
        if(k<=ans)
            return Query(lson[x],lson[y],lson[f],lson[fa],k,l,mid);
        else
            return Query(rson[x],rson[y],rson[f],rson[fa],k-ans,mid+1,r);
    }
    void init()
    {
        memset(f,0,sizeof(f));
        top=0;
        for(int i=0;i<=n;i++)
            Graph[i].clear();
    }
    int main()
    {
        while(~scanf("%d%d",&n,&m))
        {
            init();
            t=(int)(log(n)/log(2))+1;
            for(int i=1;i<=n;i++)
            {
                scanf("%d",&a[i]);
                b[i]=a[i];
            }
            sort(b+1,b+n+1);
            len=unique(b+1,b+n+1)-(b+1);
            for(int i=1;i<=n;i++)
                num[i]=lower_bound(b+1,b+len+1,a[i])-b;
            for(int i=1;i<n;i++)
            {
                int u,v;
                scanf("%d%d",&u,&v);
                Graph[u].push_back(v);
                Graph[v].push_back(u);
            }
            bfs();
            Build(root[0],1,len);
            dfs(1,0);
            while(m--)
            {
                int x,y,k;
                scanf("%d%d%d",&x,&y,&k);
                int fa = lca(x,y);
                int ans = Query(root[x],root[y],root[fa],root[f[fa][0]],k,1,len);
                printf("%d
    ",b[ans]);
            }
        }
        return 0;
    }
  • 相关阅读:
    Python—字符编码转换、函数基本操作
    零散知识点
    Python—集合的操作、文件的操作
    Python—字典的操作
    Python—字符串的操作
    Spring基础—— 在 Spring Config 中使用外部属性文件
    Spring基础—— Bean 的作用域
    Spring基础——在 IOC 容器中 Bean 之间的关系
    Spring基础——在 Spring Config 文件中基于 XML 的 Bean 的自动装配
    Spring基础——一个简单的例子
  • 原文地址:https://www.cnblogs.com/zcb123456789/p/11955424.html
Copyright © 2020-2023  润新知