• COJ 1011 WZJ的数据结构(十一)树上k大


    题解:主席树&DFS序。

    PS:为什么我一开始Wa了N发 是因为有一个左区间我写成[L,M+1]了。。。。。。。。。。。。。。。。。。。。。。。。。。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<algorithm>
     5 #include<queue>
     6 #include<cstring>
     7 #define PAU putchar(' ')
     8 #define ENT putchar('
    ')
     9 using namespace std;
    10 const int maxn=100000+10,maxnode=20000000+10,maxn2=200000+10;
    11 int ls[maxnode],rs[maxnode],s[maxnode],A[maxn],root[maxn],p[maxn],si[maxn],so[maxn],siz[maxn],cz=0,tot=0;
    12 struct tedge{int x,y,next;}adj[maxn2];int ms=0,fch[maxn];
    13 void addedge(int u,int v){
    14     adj[++ms]=(tedge){u,v,fch[u]};fch[u]=ms;
    15     adj[++ms]=(tedge){v,u,fch[v]};fch[v]=ms;
    16     return;
    17 }
    18 void build(int x,int&y,int L,int R,int pos){
    19     s[y=++tot]=s[x]+1;if(L==R) return;
    20     int M=L+R>>1;21     if(pos<=M) rs[y]=rs[x],build(ls[x],ls[y],L,M,pos);
    22     else ls[y]=ls[x],build(rs[x],rs[y],M+1,R,pos);
    23 }
    24 int query(int x,int y,int L,int R,int k){
    25     if(L==R) return L;int M=L+R>>1,kth=s[ls[y]]-s[ls[x]];
    26     if(k<=kth) return query(ls[x],ls[y],L,M,k);
    27     else return query(rs[x],rs[y],M+1,R,k-kth);
    28 }
    29 void dfs(int u,int fa){
    30     si[u]=++cz;p[cz]=u;siz[u]=1;
    31     for(int i=fch[u];i;i=adj[i].next){
    32         int v=adj[i].y;
    33         if(v!=fa) dfs(v,u),siz[u]+=siz[v];
    34     } so[u]=cz;return;
    35 }
    36 inline int read(){
    37     int x=0,sig=1;char ch=getchar();
    38     while(!isdigit(ch)){if(ch=='-')sig=-1;ch=getchar();}
    39     while(isdigit(ch))x=10*x+ch-'0',ch=getchar();
    40     return x*=sig;
    41 }
    42 inline void write(int x){
    43     if(x==0){putchar('0');return;}if(x<0)putchar('-'),x=-x;
    44     int len=0,buf[15];while(x)buf[len++]=x%10,x/=10;
    45     for(int i=len-1;i>=0;i--)putchar(buf[i]+'0');return;
    46 }
    47 int n,Q;
    48 void init(){
    49     n=read();Q=read();
    50     for(int i=1;i<n;i++) addedge(read(),read());
    51     for(int i=1;i<=n;i++) A[i]=read();
    52     dfs(1,0);
    53     for(int i=1;i<=n;i++) build(root[i-1],root[i],1,n,A[p[i]]);
    54     return;
    55 }
    56 void work(){
    57     int x,k;
    58     while(Q--){
    59         x=read();k=read();
    60         if(siz[x]<k) puts("-1");
    61         else write(query(root[si[x]-1],root[so[x]],1,n,k)),ENT;
    62     }
    63     return;
    64 }
    65 void print(){
    66     return;
    67 }
    68 int main(){init();work();print();return 0;}
  • 相关阅读:
    20190710-汉诺塔算法
    20190705-Python数据驱动之DDT
    20190621-N皇后
    还在为Excel合并单元格导致的各种问题烦恼吗?这里一起解决
    Excel基础:开始菜单之对齐方式,那些被遗忘的实用功能
    Excel中身份证号码如何分段显示,难倒小编,有什么好方法吗?
    制作这样的Excel注水图表,让老板另眼相看,坐等升职加薪
    Excel高手都会的Shift快捷键7个用法,让工作效率翻倍
    Excel答粉丝问:批量将单元格内容转为批注
    Excel基础:开始菜单之字体的华丽转身
  • 原文地址:https://www.cnblogs.com/chxer/p/4526730.html
Copyright © 2020-2023  润新知