zoukankan      html  css  js  c++  java
  • 洛谷 2633 BZOJ 2588 Spoj 10628. Count on a tree

    【题解】

      蜜汁强制在线。。。

      每个点开一个从它到根的可持久化权值线段树。查询的时候利用差分的思想在树上左右横跳就好了。

      

     1 #include<cstdio>
     2 #include<algorithm>
     3 #define N 100010
     4 #define rg register
     5 #define ls (a[u].l)
     6 #define rs (a[u].r)
     7 using namespace std;
     8 int n,n2,m,tot,root[N],last[N],dep[N],top[N],hvy[N],fa[N],size[N],val[N],b[N];
     9 struct tree{
    10     int sum,l,r;
    11 }a[N*80];
    12 struct edge{
    13     int to,pre;
    14 }e[N<<1];
    15 inline int read(){
    16     int k=0,f=1; char c=getchar();
    17     while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar();
    18     while('0'<=c&&c<='9')k=k*10+c-'0',c=getchar();
    19     return k*f;
    20 }
    21 inline int qlca(int x,int y){
    22     int f1=top[x],f2=top[y];
    23     while(f1!=f2){
    24         if(dep[f1]<dep[f2]) swap(x,y),swap(f1,f2);
    25         x=fa[f1]; f1=top[x];
    26     }
    27     return dep[x]<dep[y]?x:y;
    28 }
    29 void update(int &u,int l,int r,int pos){
    30     a[++tot]=a[u]; a[u=tot].sum++;
    31     if(l==r) return;
    32     int mid=(l+r)>>1;
    33     if(pos<=mid) update(ls,l,mid,pos);
    34     else update(rs,mid+1,r,pos);
    35 }
    36 int query(int u,int v,int lca,int f,int l,int r,int k){
    37     if(l==r) return l;
    38     int tmp=a[ls].sum+a[a[v].l].sum-a[a[lca].l].sum-a[a[f].l].sum,mid=(l+r)>>1;
    39     return k<=tmp?query(ls,a[v].l,a[lca].l,a[f].l,l,mid,k):query(rs,a[v].r,a[lca].r,a[f].r,mid+1,r,k-tmp);
    40 }
    41 void dfs1(int x){
    42     size[x]=1; dep[x]=dep[fa[x]]+1;
    43     root[x]=root[fa[x]]; update(root[x],1,n2,val[x]);
    44     for(rg int i=last[x],to;i;i=e[i].pre)if((to=e[i].to)!=fa[x]){
    45         fa[to]=x; dfs1(to);
    46         size[x]+=size[to];
    47         if(size[to]>size[hvy[x]]) hvy[x]=to;
    48     }
    49 }
    50 void dfs2(int x,int tp){
    51     top[x]=tp;
    52     if(hvy[x]) dfs2(hvy[x],tp);
    53     for(rg int i=last[x],to;i;i=e[i].pre)
    54         if((to=e[i].to)!=fa[x]&&to!=hvy[x]) dfs2(to,to);
    55 }
    56 int main(){
    57     n=read(); m=read();
    58     for(rg int i=1;i<=n;i++) val[i]=b[i]=read();
    59     sort(b+1,b+1+n); n2=unique(b+1,b+1+n)-b-1;
    60     for(rg int i=1;i<=n;i++) val[i]=lower_bound(b+1,b+1+n2,val[i])-b;
    61     for(rg int i=1;i<n;i++){
    62         int u=read(),v=read();
    63         e[++tot]=(edge){v,last[u]}; last[u]=tot;
    64         e[++tot]=(edge){u,last[v]}; last[v]=tot;
    65     }
    66     tot=0; dfs1(1); dfs2(1,1);
    67     int last=0;
    68     while(m--){
    69         int u=read()^last,v=read(),k=read(),l=qlca(u,v),f=fa[l];
    70         printf("%d
    ",last=b[query(root[u],root[v],root[l],root[f],1,n2,k)]);
    71     }
    72     return 0;
    73 }
    View Code
  • 相关阅读:
    使用Lazy对构造进行重构后比较
    Ninject Lazy Load
    在 MVC 中使用 ninject Lazy Load的一个想法
    在Ninject 向构造参数中注入具有相同类型的参数
    关于 SimpleMembership 中 CreateDate 的问题
    ubuntu下谷歌浏览器字体模糊解决方案
    ubuntu双系统时间错乱
    WPS for Linux字体配置(Ubuntu 16.04)
    VS常见错误
    VMware虚拟机ubuntu显示屏幕太小解决办法
  • 原文地址:https://www.cnblogs.com/DriverLao/p/8796247.html
Copyright © 2011-2022 走看看