zoukankan      html  css  js  c++  java
  • SPOJ Count on a tree

    Count on a tree
    Time Limit:129MS     Memory Limit:1572864KB     64bit IO Format:%lld & %llu

    Description

    You are given a tree with N nodes.The tree nodes are numbered from 1 to N.Each node has an integer weight.

    We will ask you to perform the following operation:

    • u v k : ask for the kth minimum weight on the path from node u to node v

    Input

    In the first line there are two integers N and M.(N,M<=100000)

    In the second line there are N integers.The ith integer denotes the weight of the ith node.

    In the next N-1 lines,each line contains two integers u v,which describes an edge (u,v).

    In the next M lines,each line contains three integers u v k,which means an operation asking for the kth minimum weight on the path from node u to node v.

    Output

    For each operation,print its result.

    Example

    Input:
    8 5
    8 5
    105 2 9 3 8 5 7 7
    1 2        
    1 3
    1 4
    3 5
    3 6
    3 7
    4 8
    2 5 1
    2 5 2
    2 5 3
    2 5 4
    7 8 2 
    Output:
    2
    8
    9
    105

    分析:tarjan(st表)+主席树,加了一下读入挂,挺快的;
    代码:
    st表:
    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <algorithm>
    #include <climits>
    #include <cstring>
    #include <string>
    #include <set>
    #include <map>
    #include <queue>
    #include <stack>
    #include <vector>
    #include <list>
    #define rep(i,m,n) for(i=m;i<=n;i++)
    #define rsp(it,s) for(set<int>::iterator it=s.begin();it!=s.end();it++)
    #define mod 1000000007
    #define inf 0x3f3f3f3f
    #define vi vector<int>
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    #define ll long long
    #define pi acos(-1.0)
    #define pii pair<int,int>
    #define Lson L, mid, rt<<1
    #define Rson mid+1, R, rt<<1|1
    const int maxn=4e6+10;
    using namespace std;
    ll gcd(ll p,ll q){return q==0?p:gcd(q,p%q);}
    ll qpow(ll p,ll q){ll f=1;while(q){if(q&1)f=f*p;p=p*p;q>>=1;}return f;}
    int n,m,k,t,a[maxn],b[maxn],s[maxn],ls[maxn],rs[maxn],root[maxn],h[maxn],p[maxn],dep[maxn],vis[maxn],sz,num,tot,all;
    pii st[30][maxn];
    inline ll read()
    {
        ll x=0;int f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    void init()
    {
        for(int i=2;i<=all;i++)p[i]=1+p[i>>1];
        for(int i=1;i<=29;i++)
            for(int j=1;(ll)j+(1<<i)-1<=all;j++)
                st[i][j]=min(st[i-1][j],st[i-1][j+(1<<(i-1))]);
    }
    int query(int l,int r)
    {
        int x=p[r-l+1];
        return min(st[x][l],st[x][r-(1<<x)+1]).se;
    }
    struct node
    {
        int to,nxt;
    }e[maxn];
    void add(int x,int y)
    {
        tot++;
        e[tot].to=y;
        e[tot].nxt=h[x];
        h[x]=tot;
    }
    void insert(int l,int r,int x,int &y,int v)
    {
        y=++sz;
        s[y]=s[x]+1;
        if(l==r)return;
        ls[y]=ls[x],rs[y]=rs[x];
        int mid=l+r>>1;
        if(v<=mid)insert(l,mid,ls[x],ls[y],v);
        else insert(mid+1,r,rs[x],rs[y],v);
    }
    int gao(int l,int r,int x,int y,int z,int k,int care)
    {
        if(l==r)return l;
        int mid=l+r>>1,j;
        j=s[ls[y]]+s[ls[z]]-2*s[ls[x]]+(care>=l&&care<=mid);
        if(j>=k)return gao(l,mid,ls[x],ls[y],ls[z],k,care);
        else return gao(mid+1,r,rs[x],rs[y],rs[z],k-j,care);
    }
    void dfs(int now,int pre)
    {
        st[0][++all]=mp(dep[now],now);
        vis[now]=all;
        insert(1,num,root[pre],root[now],a[now]);
        for(int i=h[now];i;i=e[i].nxt)
        {
            int to=e[i].to;
            if(to!=pre)
            {
                dep[to]=dep[now]+1;
                dfs(to,now);
                st[0][++all]=mp(dep[now],now);
            }
        }
    }
    int main()
    {
        int i,j;
        scanf("%d%d",&n,&m);
        rep(i,1,n)a[i]=read(),b[i]=a[i];
        sort(b+1,b+n+1);
        num=unique(b+1,b+n+1)-b-1;
        rep(i,1,n)a[i]=lower_bound(b+1,b+num+1,a[i])-b;
        rep(i,1,n-1)
        {
            int c,d;
            c=read(),d=read();
            add(c,d);add(d,c);
        }
        dfs(1,0);
        init();
        rep(i,1,m)
        {
            int c,d,k;
            c=read(),d=read(),k=read();
            if(vis[c]>vis[d])swap(c,d);
            int fa=query(vis[c],vis[d]);
            printf("%d
    ",b[gao(1,num,root[fa],root[c],root[d],k,a[fa])]);
        }
        //system("Pause");
        return 0;
    }
    
    
    Tarjan:
    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <algorithm>
    #include <climits>
    #include <cstring>
    #include <string>
    #include <set>
    #include <map>
    #include <queue>
    #include <stack>
    #include <vector>
    #include <list>
    #define rep(i,m,n) for(i=m;i<=n;i++)
    #define rsp(it,s) for(set<int>::iterator it=s.begin();it!=s.end();it++)
    #define mod 1000000007
    #define inf 0x3f3f3f3f
    #define vi vector<int>
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    #define ll long long
    #define pi acos(-1.0)
    #define pii pair<int,int>
    #define Lson L, mid, rt<<1
    #define Rson mid+1, R, rt<<1|1
    const int maxn=4e6+10;
    using namespace std;
    ll gcd(ll p,ll q){return q==0?p:gcd(q,p%q);}
    ll qpow(ll p,ll q){ll f=1;while(q){if(q&1)f=f*p;p=p*p;q>>=1;}return f;}
    int n,m,k,t,a[maxn],b[maxn],s[maxn],ls[maxn],rs[maxn],root[maxn],vis[maxn],ans[maxn],fa[maxn],h[maxn],g[maxn],sz,num,tot,tot1;
    struct node
    {
        int x,y,z;
        node(){}
        node(int _x,int _y,int _z):x(_x),y(_y),z(_z){};
    };
    struct node1
    {
        int to,nxt;
    }e[maxn];
    struct node2
    {
        node p;
        int nxt;
    }f[maxn];
    void add(int x,int y)
    {
        tot++;
        e[tot].to=y;
        e[tot].nxt=h[x];
        h[x]=tot;
    }
    void add1(int x,int y,int z,int k)
    {
        tot1++;
        f[tot1].p=node(y,z,k);
        f[tot1].nxt=g[x];
        g[x]=tot1;
    }
    inline ll read()
    {
        ll x=0;int f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    
    int find(int x)
    {
        return fa[x]==x?x:fa[x]=find(fa[x]);
    }
    void insert(int l,int r,int x,int &y,int v)
    {
        y=++sz;
        s[y]=s[x]+1;
        if(l==r)return;
        ls[y]=ls[x],rs[y]=rs[x];
        int mid=l+r>>1;
        if(v<=mid)insert(l,mid,ls[x],ls[y],v);
        else insert(mid+1,r,rs[x],rs[y],v);
    }
    int gao(int l,int r,int x,int y,int z,int k,int care)
    {
        if(l==r)return l;
        int mid=l+r>>1,j;
        j=s[ls[y]]+s[ls[z]]-2*s[ls[x]]+(care>=l&&care<=mid);
        if(j>=k)return gao(l,mid,ls[x],ls[y],ls[z],k,care);
        else return gao(mid+1,r,rs[x],rs[y],rs[z],k-j,care);
    }
    void dfs(int now,int pre)
    {
        vis[now]=1;
        insert(1,num,root[pre],root[now],a[now]);
        for(int i=g[now];i;i=f[i].nxt)
        {
            node p=f[i].p;
            if(vis[p.y])
            {
                int fa=find(p.y);
                ans[p.x]=b[gao(1,num,root[fa],root[now],root[p.y],p.z,a[fa])];
            }
        }
        for(int i=h[now];i;i=e[i].nxt)
        {
            int to=e[i].to;
            if(!vis[to])
            {
                dfs(to,now);
                fa[to]=now;
            }
        }
    }
    int main()
    {
        int i,j;
        scanf("%d%d",&n,&m);
        rep(i,1,n)a[i]=read(),b[i]=a[i],fa[i]=i;
        sort(b+1,b+n+1);
        num=unique(b+1,b+n+1)-b-1;
        rep(i,1,n)a[i]=lower_bound(b+1,b+num+1,a[i])-b;
        rep(i,1,n-1)
        {
            int c,d;
            c=read(),d=read();
            add(c,d);add(d,c);
        }
        rep(i,1,m)
        {
            int c,d,k;
            c=read(),d=read(),k=read();
            add1(c,i,d,k);
            add1(d,i,c,k);
        }
        dfs(1,0);
        rep(i,1,m)printf("%d
    ",ans[i]);
        //system("Pause");
        return 0;
    }
  • 相关阅读:
    【瞎口胡】基础数学 1 快速幂 整除 最大公约数
    【瞎口胡】二分图
    Windos下使用Redis
    VUE的踩坑日记(1)
    公告
    [维度打击]最大连续子序列
    常用函数
    树状数组
    高精度封装
    T4 模板之 单个文件
  • 原文地址:https://www.cnblogs.com/dyzll/p/5923269.html
Copyright © 2011-2022 走看看