zoukankan      html  css  js  c++  java
  • bzoj2588 Spoj 10628. Count on a tree

    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

    N,M<=100000
    暴力自重。。。

    正解:树上主席树

    利用树上前缀和的思想来进行主席树的操作,用dfs序存储每个结点的信息,然后就是道主席树版子题了。。

     1 //It is made by wfj_2048~
     2 #include <algorithm>
     3 #include <iostream>
     4 #include <cstring>
     5 #include <cstdlib>
     6 #include <cstdio>
     7 #include <vector>
     8 #include <cmath>
     9 #include <queue>
    10 #include <stack>
    11 #include <map>
    12 #include <set>
    13 #define inf 1<<30
    14 #define il inline
    15 #define RG register
    16 #define ll long long
    17 #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
    18 
    19 using namespace std;
    20 
    21 struct edge{ int nt,to; }g[200010];
    22 
    23 int head[100010],size[100010],dep[100010],dfn[100010],top[100010],fa[100010],son[100010],a[100010],num[100010],hashh[100010],root[100010],sum[5000010],ls[5000010],rs[5000010],m,n,N,sz,tot,cnt,pre;
    24 
    25 il int gi(){
    26     RG int x=0,q=0; RG char ch=getchar();
    27     while ((ch<'0' || ch>'9') && ch!='-') ch=getchar(); if (ch=='-') q=1,ch=getchar();
    28     while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar(); return q ? -x : x;
    29 }
    30 
    31 il void ins(RG int from,RG int to){ g[++N]=(edge){head[from],to},head[from]=N; return; }
    32 
    33 il void insert(RG int l,RG int r,RG int x,RG int &y,RG int v){
    34     y=++sz,sum[y]=sum[x]+1; if (l==r) return; ls[y]=ls[x],rs[y]=rs[x]; RG int mid=(l+r)>>1;
    35     if (v<=mid) insert(l,mid,ls[x],ls[y],v); else insert(mid+1,r,rs[x],rs[y],v); return;
    36 }
    37 
    38 il void dfs1(RG int x,RG int p){
    39     dfn[x]=++cnt,dep[x]=dep[p]+1,fa[x]=p,size[x]=1; RG int v,mx=0;
    40     for (RG int i=head[x];i;i=g[i].nt){
    41     v=g[i].to; if (v==p) continue; dfs1(v,x);
    42     size[x]+=size[v]; if (size[mx]<size[v]) mx=v;
    43     }
    44     son[x]=mx; return;
    45 }
    46 
    47 il void dfs2(RG int x,RG int p,RG int anc){
    48     insert(1,tot,root[dfn[p]],root[dfn[x]],lower_bound(hashh+1,hashh+tot+1,a[x])-hashh);
    49     top[x]=anc; if (son[x]) dfs2(son[x],x,anc); RG int v;
    50     for (RG int i=head[x];i;i=g[i].nt){
    51     v=g[i].to; if (v==p || v==son[x]) continue; dfs2(v,x,v);
    52     }
    53     return;
    54 }
    55 
    56 il int lca(RG int u,RG int v){
    57     RG int t; while (top[u]!=top[v]){ if (dep[top[u]]<dep[top[v]]) t=u,u=v,v=t; u=fa[top[u]]; }
    58     if (dep[u]<dep[v]) return u; else return v;
    59 }
    60 
    61 il int query(RG int a,RG int b,RG int k){
    62     RG int c=lca(a,b),d=fa[c],L=1,R=tot,mid,tmp;
    63     a=root[dfn[a]],b=root[dfn[b]],c=root[dfn[c]],d=root[dfn[d]];
    64     while (L<R){
    65     mid=(L+R)>>1,tmp=sum[ls[a]]+sum[ls[b]]-sum[ls[c]]-sum[ls[d]];
    66     if (k<=tmp) R=mid,a=ls[a],b=ls[b],c=ls[c],d=ls[d];
    67     else L=mid+1,k-=tmp,a=rs[a],b=rs[b],c=rs[c],d=rs[d];
    68     }
    69     return hashh[L];
    70 }
    71 
    72 il void work(){
    73     n=gi(),m=gi(); for (RG int i=1;i<=n;++i) num[i]=a[i]=gi();
    74     for (RG int i=1;i<n;++i){ RG int u=gi(),v=gi(); ins(u,v),ins(v,u); } sort(num+1,num+n+1);
    75     hashh[++tot]=num[1]; for (RG int i=2;i<=n;++i) if (num[i]!=num[i-1]) hashh[++tot]=num[i];
    76     dfs1(1,0),dfs2(1,0,1);
    77     for (RG int i=1;i<=m;++i){
    78     RG int u=gi(),v=gi(),k=gi(); pre=query(u^pre,v,k);
    79     printf("%d",pre); if (i!=m) printf("
    ");
    80     }
    81     return;
    82 }
    83 
    84 int main(){
    85     File("chairtree");
    86     work();
    87     return 0;
    88 }
  • 相关阅读:
    [SUCTF 2019]EasySQL
    [强网杯 2019]随便注
    [HCTF 2018]WarmUp
    Linux下配置JDK环境
    Centos克隆虚拟机后配置网络
    Sublime安装插件
    LeetCode-91-解码方法
    LeetCode-322-零钱兑换
    LeetCode-152-乘积最大子数组
    LeetCode-139-单词拆分
  • 原文地址:https://www.cnblogs.com/wfj2048/p/6416607.html
Copyright © 2011-2022 走看看