zoukankan      html  css  js  c++  java
  • 主席树+dfs SPOJ BZOJ2588 Count on a tree

    这道题我由于智障错误导致一直错。

    在树上建主席树,加上lca思想,很简单。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int N=200005;
     4 struct node
     5 {
     6     int to,nex;
     7 }e[N<<1];
     8 struct tree
     9 {
    10     int l,r,s;
    11 }t[2000005];
    12 int n,m,cnt,cn,mx,pre,head[N],f[N][21],a[N],rt[N],d[N];
    13 vector<int>v;
    14 inline int get(int x){return lower_bound(v.begin(),v.end(),x)-v.begin()+1;}
    15 void add(int x,int y)
    16 {
    17     e[++cnt].to=y;e[cnt].nex=head[x];head[x]=cnt;
    18 }
    19 void update(int &x,int l,int r,int p,int num)
    20 {
    21     x=++cn;t[x]=t[p];t[x].s++;int mid=l+r>>1;
    22     if(l==r)return ;
    23     if(mid>=num)update(t[x].l,l,mid,t[p].l,num);
    24     else update(t[x].r,mid+1,r,t[p].r,num);
    25 }
    26 void dfs(int x,int fa)
    27 {
    28     update(rt[x],1,mx,rt[fa],get(a[x]));f[x][0]=fa;d[x]=d[fa]+1;
    29     for(int i=1;i<=20;++i)
    30     if(d[x]>=(1<<i))
    31     f[x][i]=f[f[x][i-1]][i-1];
    32     for(int i=head[x];i;i=e[i].nex)
    33     {
    34         int y=e[i].to;
    35         if(y==fa)continue;
    36         dfs(y,x);
    37     }
    38 }
    39 int lca(int x,int y)
    40 {
    41     if(d[x]<d[y])swap(x,y);
    42     int tmp=d[x]-d[y];
    43     for(int i=20;i>=0;i--)
    44     if(tmp&(1<<i))x=f[x][i];
    45     for(int i=20;i>=0;i--)
    46     {
    47         if(f[x][i]!=f[y][i])
    48             x=f[x][i],y=f[y][i];
    49     }
    50     return x==y?x:f[x][0];
    51 }
    52 int query(int l,int r,int rt1,int rt2,int rt3,int rt4,int k)
    53 {
    54     if(l==r){
    55         pre=v[l-1];return l;
    56     }
    57     int sum=t[t[rt1].l].s+t[t[rt2].l].s-t[t[rt3].l].s-t[t[rt4].l].s;
    58     int mid=(l+r)>>1;
    59     if(sum>=k)return query(l,mid,t[rt1].l,t[rt2].l,t[rt3].l,t[rt4].l,k);
    60     else return query(mid+1,r,t[rt1].r,t[rt2].r,t[rt3].r,t[rt4].r,k-sum);
    61 }
    62 int main()
    63 {
    64     //freopen("rand.out","r",stdin);
    65     //freopen("my.out","w",stdout);
    66     int x,y,k;
    67     scanf("%d%d",&n,&m);
    68     for(int i=1;i<=n;++i)
    69     {
    70         scanf("%d",&a[i]);v.push_back(a[i]);
    71     }
    72     sort(v.begin(),v.end());v.erase(unique(v.begin(),v.end()),v.end());mx=v.size();
    73     for(int i=1;i<n;++i)
    74     {
    75         scanf("%d%d",&x,&y);
    76         add(x,y);add(y,x);
    77     }
    78     dfs(1,0);
    79     for(int i=1;i<=m;++i)
    80     {
    81         scanf("%d%d%d",&x,&y,&k);
    82         int z=lca(pre^x,y);
    83         printf("%d",v[query(1,mx,rt[pre^x],rt[y],rt[z],rt[f[z][0]],k)-1]);
    84         if(i<m) puts("");
    85     }
    86     return 0;
    87 }

    BZOJ最后换行会PE。。。。

  • 相关阅读:
    12345679*81=?
    怪异,漂亮的几个数学恒等式(转)
    道路着色问题
    一组数学算式的欣赏(转)
    数学中奇妙的“金蝉脱壳”(转)
    数学中的分分合合(转)
    四方定理和卡布列克常数(转)
    简单的题目 有趣的现象
    Android学习笔记 第三节 基本控件学习
    Android学习笔记 第二节 HelloWorld程序
  • 原文地址:https://www.cnblogs.com/nbwzyzngyl/p/8012825.html
Copyright © 2011-2022 走看看