zoukankan      html  css  js  c++  java
  • bzoj2588

    2588: Spoj 10628. Count on a tree

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

    题解:
      呵呵,傻逼题目搞我半天(tmd  RE你是要上天啊) 就是求一颗树上区间第k大》》》So easy 妈妈在也不用担心我会RE
      1 #include<iostream>
      2 #include<cstring>
      3 #include<cstdio>
      4 #include<algorithm>
      5 #include<cmath>
      6 #define maxn 200010
      7 #define maxnode 8000000
      8 using namespace std;
      9 int deep[maxn],fa[maxn][20],bin[20];
     10 int pre[maxn*2],now[maxn],v[maxn*2];
     11 int a[maxn],list[maxn];
     12 int son[maxnode][2],rt[maxn],sum[maxnode];
     13 int root,size,tot,n,m,lastans;
     14 
     15 int read()
     16 {
     17     int x=0; char ch; bool bo=0;
     18     while (ch=getchar(),ch<'0'||ch>'9') if (ch=='-') bo=1;
     19     while (x=x*10+ch-'0',ch=getchar(),ch>='0'&&ch<='9');
     20     if (bo) return -x; return x;
     21 }
     22 void insert(int x,int y){++tot; pre[tot]=now[x]; now[x]=tot; v[tot]=y;}
     23 void ins(int x,int y){ insert(x,y); insert(y,x);
     24 }
     25 void build()
     26 {
     27     root=0;
     28     for (int i=1; i<=n-1; i++)
     29     {
     30         int x=read(), y=read();
     31         ins(x,y);
     32         if (!root || root==y) root=x;
     33     }
     34 }
     35 void prework()
     36 {
     37     bin[0]=1;
     38     for (int i=1; i<=17; i++) bin[i]=bin[i-1]<<1;
     39 }
     40 void add(int x, int &y, int val)
     41 {
     42     y=++size; sum[y]=sum[x]+1; int t,pos=y; 
     43     int l=1,r=n;
     44     while (l<r)
     45     {
     46         int mid=(l+r)>>1;
     47         if (val<=mid) t=0,r=mid; else t=1,l=mid+1;
     48         son[y][t^1]=son[x][t^1];
     49         son[y][t]=++size;
     50         y=son[y][t]; x=son[x][t];
     51         sum[y]=sum[x]+1;
     52     }
     53     y=pos;
     54 }
     55 void dfs(int x,int father)
     56 {
     57     //cout<<"                                       dfs         "<<x<<endl;
     58     deep[x]=deep[father]+1;
     59     fa[x][0]=father;
     60     for (int i=1; i<=17; i++)
     61         if (deep[x]>=bin[i])
     62         fa[x][i]=fa[fa[x][i-1]][i-1];
     63     for (int p=now[x]; p; p=pre[p])
     64     {
     65         int rz=v[p];
     66         if (rz!=father)
     67         {
     68             add(rt[x],rt[rz],a[rz]);
     69             dfs(rz,x);
     70         }
     71     }
     72 }
     73 int lca(int x,int y)
     74 {
     75     if (deep[x]<deep[y]) swap(x,y);
     76     int t=deep[x]-deep[y];
     77     for (int i=0; bin[i]<=t; i++)
     78     {
     79         if (t&bin[i]) x=fa[x][i];
     80     }
     81     for (int i=16; i>=0; i--)
     82         if (fa[x][i]!=fa[y][i])
     83             x=fa[x][i],y=fa[y][i];
     84     if (x==y) return x; else return fa[x][0];
     85 }
     86 int query(int x, int y, int val)
     87 {
     88     int dad=lca(x,y),dd;
     89     x=rt[x],y=rt[y];
     90     dd=fa[dad][0];
     91     dad=rt[dad],dd=rt[dd];
     92     int l=1,r=n;
     93     while (l<r)
     94     {
     95         int mid=(l+r)>>1;  int t=0;
     96         int kk=sum[son[x][t]]+sum[son[y][t]]-sum[son[dad][t]]-sum[son[dd][t]];
     97     //    cout<<kk<<endl;
     98         if (kk>=val)
     99         {
    100             r=mid; x=son[x][t]; y=son[y][t]; dad=son[dad][t],dd=son[dd][t];
    101         }
    102         else
    103         {
    104             l=mid+1; x=son[x][t^1]; y=son[y][t^1]; val-=kk,dad=son[dad][t^1],dd=son[dd][t^1];
    105         }
    106     }
    107     return list[l];
    108 }
    109 
    110 int main()
    111 {
    112     prework();
    113     n=read(); m=read();
    114     for (int i=1; i<=n; i++)
    115         a[i]=list[i]=read();
    116     sort(list+1,list+n+1);
    117     for (int i=1; i<=n; i++)
    118         a[i]=lower_bound(list+1,list+n+1,a[i])-list;
    119     build();
    120     add(rt[0],rt[root],a[root]);
    121     dfs(root,0);
    122     lastans=0;
    123     while (m--)
    124     {
    125         int x=read(),y=read(),val=read();
    126         x^=lastans;
    127         lastans=query(x,y,val);
    128         if (m!=0) printf("%d
    ",lastans); else printf("%d",lastans);
    129     }
    130 }
    View Code
  • 相关阅读:
    01 React快速入门(一)——使用循环时对于‘key’报错处理
    01 div实现浮动效果
    17 制作热力图
    16 ArcGIS Server 10.6.1发布影像服务
    虚拟机上有关于Apache服务基于主机名@4域名访问网页
    虚拟机上有关于Apache服务基于IP地址@3IP访问网站
    Apache有关个人用户主页以及强制访问安全系统功能介绍@2
    Apache服务的安装以及服务文件参数内容的配置 @1
    WVware虚拟机linux环境下使用ssh服务以安全密钥的形式远程控制服务(本地客户端登录远程服务端)
    WVware虚拟机linux环境下RAID5 五块磁盘操作管理实例
  • 原文地址:https://www.cnblogs.com/HQHQ/p/5449038.html
Copyright © 2011-2022 走看看