• BZOJ2588 [SPOJ10628]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
    正解:主席树
     
    解题报告:感觉主席树不是很熟练,想练一练,就打一道练练手,今天竟然一次打对AC,当然第一次的PE不算在里面。
     
      1 #include <iostream>
      2 #include <iomanip>
      3 #include <cstdlib>
      4 #include <cstdio>
      5 #include <cstring>
      6 #include <cmath>
      7 #include <algorithm>
      8 #include <string>
      9 #define RG register
     10 const int N = 3000000;
     11 const int M = 300000;
     12 
     13 using namespace std;
     14 
     15 int siz[M],nn[M*2][2],head[M],ra[M],fa[M],id[M],son[M];
     16 int cnt,dis[M],top[M],n,m,a[N],b[N],rt[M],sa[M],w[M],ans;
     17 
     18 struct date{
     19     int s,i;
     20     bool operator < (const date a) const{
     21         return s<a.s;
     22     }
     23 }f[M];
     24 
     25 int gi(){
     26     char ch=getchar();int x=0;
     27     while(ch<'0' || ch>'9') ch=getchar();
     28     while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
     29     return x;
     30 }
     31 
     32 void dfs1(int xh,int fu){
     33     fa[xh]=fu,dis[xh]=dis[fu]+1;
     34     for (RG int i=head[xh]; i; i=nn[i][0]){
     35         if (nn[i][1]==fu) continue;
     36         dfs1(nn[i][1],xh);
     37         siz[xh]+=siz[nn[i][1]];
     38         if (siz[nn[i][1]]>siz[son[xh]])
     39             son[xh]=nn[i][1];
     40     }
     41     ++siz[xh];
     42     return;
     43 }
     44 
     45 struct dota{
     46     int s,l,r;
     47 }tr[N];
     48 
     49 void build(int x,int &t,int l,int r){
     50     tr[++ans]=tr[t];t=ans;
     51     ++tr[ans].s;
     52     if (l==r) return;
     53     int mid=(l+r)>>1;
     54     if (x<=mid) build(x,tr[ans].l,l,mid);
     55     else build(x,tr[ans].r,mid+1,r);
     56     return;
     57 }
     58 
     59 void dfs2(int xh,int tp){
     60     id[xh]=++cnt,top[xh]=tp;
     61     rt[cnt]=rt[cnt-1],build(ra[xh],rt[cnt],1,n);
     62     if (son[xh]) dfs2(son[xh],tp);
     63     for (RG int i=head[xh]; i; i=nn[i][0]){
     64         if (nn[i][1]==son[xh] || nn[i][1]==fa[xh]) continue;
     65         dfs2(nn[i][1],nn[i][1]);
     66     }
     67     return;
     68 }
     69 
     70 int query(int l,int r,int k){
     71     RG int tot=0;
     72     while(top[l]!=top[r])
     73         if (dis[top[l]]>dis[top[r]]) a[++tot]=rt[id[top[l]]-1],b[tot]=rt[id[l]],l=fa[top[l]];
     74         else a[++tot]=rt[id[top[r]]-1],b[tot]=rt[id[r]],r=fa[top[r]];
     75     if (dis[l]>dis[r]) a[++tot]=rt[id[r]-1],b[tot]=rt[id[l]];
     76     else a[++tot]=rt[id[l]-1],b[tot]=rt[id[r]];
     77     RG int z=1,y=n,mid;
     78     while(z!=y){
     79         RG int a1=0,b1=0;
     80         mid=(z+y)>>1;
     81         for (RG int i=1; i<=tot; ++i) a1+=tr[tr[a[i]].l].s;
     82         for (RG int i=1; i<=tot; ++i) b1+=tr[tr[b[i]].l].s;
     83         if (b1-a1>=k){
     84             for (RG int i=1; i<=tot; ++i) a[i]=tr[a[i]].l;
     85             for (RG int i=1; i<=tot; ++i) b[i]=tr[b[i]].l;
     86             y=mid;
     87         }
     88         else{
     89             for (RG int i=1; i<=tot; ++i) a[i]=tr[a[i]].r;
     90             for (RG int i=1; i<=tot; ++i) b[i]=tr[b[i]].r;
     91             z=mid+1,k-=(b1-a1);
     92         }
     93     }
     94     return z;
     95 }
     96 
     97 int main(){
     98     n=gi(),m=gi();
     99     for (RG int i=1; i<=n; ++i) f[i]=(date){gi(),i},w[i]=f[i].s;
    100     sort(f+1,f+n+1);
    101     for (RG int i=1; i<=n; ++i) ra[f[i].i]=i,sa[i]=f[i].i;
    102     for (RG int i=1; i<n;  ++i){
    103         RG int l=gi(),r=gi();
    104         nn[++cnt][1]=l,nn[cnt][0]=head[r],head[r]=cnt;
    105         nn[++cnt][1]=r,nn[cnt][0]=head[l],head[l]=cnt;
    106     }
    107     cnt=0;
    108     dfs1(1,0),dfs2(1,1);
    109     int jl=0;
    110     for (RG int i=1; i<m; ++i){
    111         RG int l=gi()^jl,r=gi(),k=gi();
    112         jl=query(l,r,k);
    113         printf("%d
    ",w[sa[jl]]);
    114         jl=w[sa[jl]];
    115     }
    116     RG int l=gi()^jl,r=gi(),k=gi();
    117     jl=query(l,r,k);
    118     printf("%d",w[sa[jl]]);
    119     jl=w[sa[jl]];
    120     return 0;
    121 }
  • 相关阅读:
    结构体中的冒号_转
    随机数产生random
    gdb调试段错误及使用
    gcc选项-g与-rdynamic的异同_转
    linux设备模型_转
    boost 1.57.0安装
    技术的正宗与野路子_转
    (转)Java里的堆(heap)栈(stack)和方法区(method)(精华帖,多读读)
    (转)面试大总结之一:Java搞定面试中的链表题目
    (转)类加载器与双亲委派模型
  • 原文地址:https://www.cnblogs.com/cjk2001/p/6478094.html
Copyright © 2020-2023  润新知