zoukankan      html  css  js  c++  java
  • [xdoj1216]子树第k小(dfs序+主席树)

    解题关键:dfs序将树映射到区间,然后主席树求区间第k小,为模板题。

      1 #pragma comment(linker, "/STACK:1024000000,1024000000") `
      2 #include<cstdio>
      3 #include<algorithm>
      4 #include<cstdlib>
      5 #include<cstring>
      6 #include<iostream>
      7 #include<cmath>
      8 #include<vector>
      9 typedef long long ll;
     10 using namespace std;
     11 const int maxn=1e5+4;
     12 int head[maxn],in[maxn],out[maxn],cnt,num;
     13 int b[maxn],va[maxn];
     14 int n,m;
     15 struct Edge{
     16     int to,nxt;
     17 }e[maxn<<2];
     18 int root[maxn];
     19 struct node{
     20     int l,r,sum;
     21 }p[maxn*22];
     22 
     23 inline int read(){
     24     char k=0;char ls;ls=getchar();for(;ls<'0'||ls>'9';k=ls,ls=getchar());
     25     int x=0;for(;ls>='0'&&ls<='9';ls=getchar())x=(x<<3)+(x<<1)+ls-'0';
     26     if(k=='-')x=0-x;return x;
     27 }
     28 
     29 void add_edge(int u,int v){
     30     e[cnt].to=v;
     31     e[cnt].nxt=head[u];
     32     head[u]=cnt++;
     33 }
     34 
     35 void dfs(int u,int fa){
     36     num++;
     37     b[num]=va[u];
     38     in[u]=num;
     39     for(int i=head[u];i!=-1;i=e[i].nxt){
     40         int v=e[i].to;
     41         if(v==fa) continue;
     42         dfs(v,u);
     43     }
     44     out[u]=num;
     45 }
     46 
     47 int build(int l,int r){
     48     int rt=++cnt;
     49     p[rt].sum=0;
     50     p[rt].l=p[rt].r=0;
     51     if(l==r) return rt;
     52     int mid=(l+r)>>1;
     53     p[rt].l=build(l,mid);
     54     p[rt].r=build(mid+1,r);
     55     return rt;
     56 }
     57 
     58 int update(int l,int r,int c,int k){
     59     int nc=++cnt;
     60     p[nc]=p[c];
     61     p[nc].sum++;
     62     int mid=(l+r)>>1;
     63     if(l==r) return nc;
     64     if(mid>=k) p[nc].l=update(l,mid,p[c].l,k);
     65     else p[nc].r=update(mid+1,r,p[c].r,k);
     66     return nc;
     67 }
     68 
     69 int query(int l,int r,int x,int y,int k){
     70     if(l==r) return l;
     71     int mid=(l+r)>>1;
     72     int sum=p[p[y].l].sum-p[p[x].l].sum;
     73     if(sum>=k) return query(l,mid,p[x].l,p[y].l,k);
     74     else return query(mid+1,r,p[x].r,p[y].r,k-sum);
     75 }
     76 vector<int>v;
     77 int getid(int x){
     78     return int(lower_bound(v.begin(),v.end(),x)-v.begin())+1;
     79 }
     80 
     81 int main(){
     82     while(scanf("%d",&n)!=EOF){
     83         v.clear();
     84         memset(head,-1,sizeof head);
     85         cnt=0;
     86         num=0;
     87         for(int i=1;i<=n;i++)    va[i]=read();
     88         for(int i=0;i<n-1;i++){
     89             int t1,t2;
     90             t1=read();
     91             t2=read();
     92             add_edge(t1,t2);
     93             add_edge(t2,t1);
     94         }
     95         dfs(1,-1);
     96         for(int i=1;i<=n;i++) v.push_back(b[i]);        
     97         sort(v.begin(),v.end());
     98         v.erase(unique(v.begin(), v.end()),v.end());
     99         root[0]=build(1,n);
    100         for(int i=1;i<=n;i++) root[i]=update(1,n,root[i-1],getid(b[i]));
    101         int c,d;
    102         m=read();
    103         for(int i=0;i<m;i++){
    104             c=read();
    105             d=read();
    106             int ans=query(1,n,root[in[c]-1],root[out[c]],d);
    107             printf("%d
    ",v[ans-1]);
    108         }
    109     }
    110     return 0;
    111 }
  • 相关阅读:
    函数重载及缺省参数
    巨大的斐波那契数!
    求任意多边形的面积
    hdu1068 Girls and Boys 匈牙利算法(邻接表)
    C. Coconut(2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛)
    A. Banana (2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛)
    hdu6195 cable cable cable(from 2017 ACM/ICPC Asia Regional Shenyang Online)
    hdu6201 transaction transaction transaction(from 2017 ACM/ICPC Asia Regional Shenyang Online)
    hdu3938 Portal 离线+并查集
    同构图
  • 原文地址:https://www.cnblogs.com/elpsycongroo/p/7430053.html
Copyright © 2011-2022 走看看