zoukankan      html  css  js  c++  java
  • Bzoj 2588: Spoj 10628. Count on a tree 主席树,离散化,可持久,倍增LCA

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2588

    2588: Spoj 10628. Count on a tree

    Time Limit: 12 Sec  Memory Limit: 128 MB
    Submit: 3584  Solved: 835
    [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

    题解:

    在树上建主席树,记得最后一行后没有空格,否则PE.

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 #define MAXN 100010
      4 struct node
      5 {
      6     int begin,end,next;
      7 }edge[MAXN*2];
      8 struct NODE
      9 {
     10     int left,right;
     11 }tree[MAXN*20];
     12 int cnt,Head[MAXN],n,SIZE,value[MAXN],pos[MAXN],deep[MAXN],P[MAXN][17],sum[MAXN*20],a[MAXN],val[MAXN],root[MAXN],tot;
     13 bool vis[MAXN];
     14 void addedge(int bb,int ee)
     15 {
     16     edge[++cnt].begin=bb;edge[cnt].end=ee;edge[cnt].next=Head[bb];Head[bb]=cnt;
     17 }
     18 void addedge1(int bb,int ee)
     19 {
     20     addedge(bb,ee);addedge(ee,bb);
     21 }
     22 int read()
     23 {
     24     int s=0,fh=1;char ch=getchar();
     25     while(ch<'0'||ch>'9'){if(ch=='-')fh=-1;ch=getchar();}
     26     while(ch>='0'&&ch<='9'){s=s*10+(ch-'0');ch=getchar();}
     27     return s*fh;
     28 }
     29 void dfs1(int u)
     30 {
     31     int i,v;
     32     SIZE++;value[SIZE]=u;pos[u]=SIZE;
     33     vis[u]=true;
     34     for(i=Head[u];i!=-1;i=edge[i].next)
     35     {
     36         v=edge[i].end;
     37         if(vis[v]==false)
     38         {
     39             deep[v]=deep[u]+1;
     40             P[v][0]=u;
     41             dfs1(v);
     42         }
     43     }
     44 }
     45 void Ycl()
     46 {
     47     int i,j;
     48     for(j=1;(1<<j)<=n;j++)
     49     {
     50         for(i=1;i<=n;i++)
     51         {
     52             if(P[i][j-1]!=-1)P[i][j]=P[P[i][j-1]][j-1];
     53         }
     54     }
     55 }
     56 int LCA(int x,int y)
     57 {
     58     int i,j;
     59     if(deep[x]<deep[y])swap(x,y);
     60     for(i=0;(1<<i)<=deep[x];i++);i--;
     61     for(j=i;j>=0;j--)if(deep[x]-(1<<j)>=deep[y])x=P[x][j];
     62     if(x==y)return x;
     63     for(j=i;j>=0;j--)
     64     {
     65         if(P[x][j]!=-1&&P[x][j]!=P[y][j])
     66         {
     67             x=P[x][j];
     68             y=P[y][j];
     69         }
     70     }
     71     return P[x][0];
     72 }
     73 void Update(int x,int &y,int l,int r,int k)
     74 {
     75     y=++SIZE;
     76     sum[y]=sum[x]+1;
     77     if(l==r)return;
     78     tree[y].left=tree[x].left;tree[y].right=tree[x].right;
     79     int mid=(l+r)/2;
     80     if(k<=mid)Update(tree[x].left,tree[y].left,l,mid,k);
     81     else Update(tree[x].right,tree[y].right,mid+1,r,k);
     82 }
     83 int query(int l,int r,int A,int B,int C,int D,int k)
     84 {
     85     if(l==r)return l;
     86     int mid=(l+r)/2,tmp=sum[tree[A].left]+sum[tree[B].left]-sum[tree[C].left]-sum[tree[D].left];
     87     if(k<=tmp)return query(l,mid,tree[A].left,tree[B].left,tree[C].left,tree[D].left,k);
     88     else return query(mid+1,r,tree[A].right,tree[B].right,tree[C].right,tree[D].right,k-tmp);
     89 }
     90 int Query(int A,int B,int k)
     91 {
     92     int C=LCA(A,B),D=P[C][0];
     93     A=root[pos[A]];B=root[pos[B]];C=root[pos[C]];D=root[pos[D]];
     94     return query(1,tot,A,B,C,D,k);
     95 }
     96 int main()
     97 {
     98     int m,i,bb,ee,k,k1,lastans,U,V,K;
     99     n=read();m=read();
    100     for(i=1;i<=n;i++)a[i]=val[i]=read();
    101     sort(val+1,val+n+1);
    102     tot=unique(val+1,val+n+1)-(val+1);
    103     memset(Head,-1,sizeof(Head));cnt=1;
    104     for(i=1;i<n;i++)
    105     {
    106         bb=read();ee=read();
    107         addedge1(bb,ee);
    108     }
    109     memset(P,-1,sizeof(P));SIZE=0;
    110     memset(value,0,sizeof(value));//树上每个编号的实际的点.
    111     memset(pos,0,sizeof(pos));//每个点在树上的编号.
    112     dfs1(1);Ycl();
    113     memset(root,0,sizeof(root));
    114     SIZE=0;
    115     for(i=1;i<=n;i++)//i为树上的节点.(即i为每个点在树上的编号.)
    116     {
    117         k=value[i];
    118         k1=lower_bound(val+1,val+tot+1,a[k])-val;
    119         Update(root[pos[P[k][0]]],root[i],1,tot,k1);
    120     }
    121     lastans=0;
    122     for(i=1;i<=m;i++)
    123     {
    124         U=read();V=read();K=read();
    125         U^=lastans;
    126         lastans=val[Query(U,V,K)];
    127         printf("%d",lastans);
    128         if(i!=m)printf("
    ");
    129     }
    130     fclose(stdin);
    131     fclose(stdout);
    132     return 0;
    133 }
    View Code
  • 相关阅读:
    Java读取压缩文件信息
    中国菜刀 一句话木马
    java中equals方法和hashcode方法的区别和联系,以及为什么要重写这两个方法,不重写会怎样
    Hadoop搭建全程
    instr模糊查询使用及注意事项
    idea离线安装SonarLint
    Previous operation has not finished; run 'cleanup' if it was interrupted] 的排错过程
    vue中excel文件上传总结
    IDEA 2019.1离线安装lombok
    @Data注解失效解决办法
  • 原文地址:https://www.cnblogs.com/Var123/p/5276903.html
Copyright © 2011-2022 走看看