zoukankan      html  css  js  c++  java
  • BZOJ 2588: Spoj 10628. Count on a tree

    2588: Spoj 10628. Count on a tree

    Time Limit: 12 Sec  Memory Limit: 128 MB
    Submit: 5620  Solved: 1336
    [Submit][Status][Discuss]

    Description

    给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权。其中lastans是上一个询问的答案,初始为0,即第一个询问的u是明文。
     

    Input

    第一行两个整数N,M。
    第二行有N个整数,其中第i个整数表示点i的权值。
    后面N-1行每行两个整数(x,y),表示点x到点y有一条边。
    最后M行每行两个整数(u,v,k),表示一组询问。
     

    Output

    M行,表示每个询问的答案。最后一个询问不输出换行符

    Sample Input

    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
    0 5 2
    10 5 3
    11 5 4
    110 8 2

    Sample Output

    2
    8
    9
    105
    7

    HINT

    HINT:

    N,M<=100000

    暴力自重。。。

    Source

    鸣谢seter

    分析:

    树上的主席树,我们对于每一个节点维护一个当前结点到根节点的路径上的权值线段树,然后查询的时候对于x到y的路径我们用sum[x]+sum[y]-sum[lca]-sum[fa[lca]]来查询...

    代码:

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    //by NeighThorn
    using namespace std;
      
    const int maxn=200000+5,maxm=7000000+5;
      
    int n,m,cnt,len,tot,w[maxn],hd[maxn],mp[maxn],ls[maxm],rs[maxm],to[maxn],fa[maxn][25],nxt[maxn],sum[maxm],dep[maxn],root[maxn];
      
    inline void add(int x,int y){
        to[cnt]=y;nxt[cnt]=hd[x];hd[x]=cnt++;
    }
      
    inline int find(int x){
        int l=1,r=len,ans;
        while(l<=r){
            int mid=(l+r)>>1;
            if(mp[mid]>=x)
                ans=mid,r=mid-1;
            else
                l=mid+1;
        }
        return ans;
    }
      
    inline void change(int l,int r,int x,int &y,int val){
        y=++tot,sum[y]=sum[x]+1;
        if(l==r)
            return;
        int mid=(l+r)>>1;ls[y]=ls[x],rs[y]=rs[x];
        if(val<=mid)
            change(l,mid,ls[x],ls[y],val);
        else
            change(mid+1,r,rs[x],rs[y],val);
    }
      
    inline void dfs(int rt,int f){
        change(1,len,rt==1?root[0]:root[fa[rt][0]],root[rt],find(w[rt]));
        for(int i=hd[rt];i!=-1;i=nxt[i])
            if(to[i]!=f)
                dep[to[i]]=dep[rt]+1,fa[to[i]][0]=rt,dfs(to[i],rt);
    }
      
    inline void init(void){
        for(int j=1;j<=20;j++)
            for(int i=1;i<=n;i++)
                fa[i][j]=fa[fa[i][j-1]][j-1];
    }
      
    inline int LCA(int x,int y){
        if(dep[x]<dep[y])
            swap(x,y);
        int d=dep[x]-dep[y];
        for(int i=0;i<=20;i++)
            if((d>>i)&1)
                x=fa[x][i];
        if(x==y)
            return x;
        for(int i=20;i>=0;i--)
            if(fa[x][i]!=fa[y][i])
                x=fa[x][i],y=fa[y][i];
        return fa[x][0];
    }
      
    inline int query(int l,int r,int x,int y,int lca,int flca,int num){
        if(l==r)
            return l;
        int mid=(l+r)>>1;
        if(sum[ls[x]]+sum[ls[y]]-sum[ls[lca]]-sum[ls[flca]]>=num)
            return query(l,mid,ls[x],ls[y],ls[lca],ls[flca],num);
        else
            return query(mid+1,r,rs[x],rs[y],rs[lca],rs[flca],num-(sum[ls[x]]+sum[ls[y]]-sum[ls[lca]]-sum[ls[flca]]));
    }
      
    signed main(void){
        memset(hd,-1,sizeof(hd));
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
            scanf("%d",&w[i]),mp[i]=w[i];
        sort(mp+1,mp+n+1),len=unique(mp+1,mp+n+1)-mp-1;
        for(int i=1,x,y;i<n;i++)
            scanf("%d%d",&x,&y),add(x,y),add(y,x);
        fa[1][0]=1;dfs(1,-1);init();int ans=0,lca;
        for(int i=1,s,x,y;i<=m;i++){
            scanf("%d%d%d",&x,&y,&s),lca=LCA(ans^x,y),printf("%d",ans=mp[query(1,len,root[ans^x],root[y],root[lca],root[lca==1?0:fa[lca][0]],s)]);
            if(i<m)
                puts("");
        }
        return 0;
    }
    

      


    By NeighThorn

  • 相关阅读:
    VC 常见问题百问
    python windows 环境变量
    Check server headers and verify HTTP Status Codes
    Where are the AES 256bit cipher suites? Please someone help
    outlook 如何预订会议和会议室
    安装Axis2的eclipse插件后,未出现界面
    windows 环境变量
    python 时间日期处理汇集
    openldap学习笔记(使用openldap2.3.32)
    set p4 environment in windows
  • 原文地址:https://www.cnblogs.com/neighthorn/p/6392674.html
Copyright © 2011-2022 走看看