zoukankan      html  css  js  c++  java
  • bzoj 2588

    树上用主席树的话,对每个点到根的区间开个线段树

    然后每次询问求出lca后就能用区间减法了(链剖的代码还是挺好看的)

    弄了好久只是空间的问题,开空间也不能太随意。。

     1 #include<bits/stdc++.h>
     2 #define inc(i,l,r) for(int i=l;i<=r;i++)
     3 #define dec(i,l,r) for(int i=l;i>=r;i--)
     4 #define link(x) for(edge *j=h[x];j;j=j->next)
     5 #define mem(a) memset(a,0,sizeof(a))
     6 #define inf 1e9
     7 #define ll long long
     8 #define succ(x) (1<<x)
     9 #define NM 200000+5
    10 using namespace std;
    11 int read(){
    12     int x=0,f=1;char ch=getchar();
    13     while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    14     while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
    15     return x*f;
    16 }
    17 struct edge{
    18     int t,v;
    19     edge *next;
    20 }e[2*NM],*h[NM],*_o=e,*null;
    21 void add(int x,int y){
    22     _o++;_o->t=y;_o->next=h[x];h[x]=_o;
    23 }
    24 struct node{
    25     int s;
    26     node *l,*r;
    27 }T[20*NM],*root[NM],*o=T;
    28 int d[NM],f[NM],top[NM],son[NM],size[NM],TOP;
    29 int n,m,_t,cnt,a[NM],b[NM],_x,_y,_p;
    30 node* mod(node *p,int x,int y){
    31     int t=x+y>>1;node *r=++o;
    32     *o=*p;r->s++;
    33     if(x==y)return r;
    34     if(_t<=t)r->l=mod(p->l,x,t);
    35     else r->r=mod(p->r,t+1,y);
    36     return r;
    37 }
    38 void dfs1(int x){
    39     _t=a[x];root[x]=mod(root[f[x]],1,cnt);
    40     link(x)
    41     if(!d[j->t]){
    42         f[j->t]=x;d[j->t]=d[x]+1;
    43         dfs1(j->t);
    44         size[x]+=size[j->t];
    45         if(size[j->t]>size[son[x]])son[x]=j->t;
    46     }
    47     size[x]++;
    48 }
    49 void dfs2(int x){
    50     top[x]=TOP;
    51     if(son[x])dfs2(son[x]);
    52     link(x)if(!top[j->t])dfs2(TOP=j->t);
    53 }
    54 int lca(int x,int y){
    55     if(top[x]==top[y])return d[x]<d[y]?x:y;
    56     return d[top[x]]>d[top[y]]?lca(f[top[x]],y):lca(x,f[top[y]]);
    57 }
    58 int query(node *r1,node *r2,node *r3,node *r4,int x,int y,int k){
    59     int t=x+y>>1,v=r1->l->s+r2->l->s-r3->l->s-r4->l->s;
    60     if(x==y)return b[x];
    61     if(k<=v)return query(r1->l,r2->l,r3->l,r4->l,x,t,k);
    62     else return query(r1->r,r2->r,r3->r,r4->r,t+1,y,k-v);
    63 }
    64 int main(){
    65     freopen("data.in","r",stdin);
    66     n=read();m=read();
    67     inc(i,1,n)b[i]=a[i]=read();
    68     sort(b+1,b+n+1);
    69     cnt=unique(b+1,b+n+1)-b-1;
    70     inc(i,1,n)a[i]=lower_bound(b+1,b+cnt+1,a[i])-b;
    71     inc(i,1,n-1){
    72         _x=read();_y=read();
    73         add(_x,_y);add(_y,_x);
    74     }
    75     d[1]++;root[0]=++o;root[0]->l=o;root[0]->r=o;
    76     dfs1(1);
    77 //    inc(i,1,n)printf("%d ",son[i]);printf("
    ");
    78     dfs2(TOP=1);
    79 //    inc(i,0,n)printf("%d ",root[i]->s);printf("
    ");
    80     while(m--){
    81         _x=read()^_p;_y=read();_t=read();
    82         _p=lca(_x,_y);
    83         _p=query(root[_x],root[_y],root[_p],root[f[_p]],1,cnt,_t);
    84         printf("%d",_p);if(m)putchar('
    ');
    85     }
    86     return 0;
    87 }
    View Code
  • 相关阅读:
    Java注释Override、Deprecated、SuppressWarnings详解
    android: 实现跨程序数据共享
    android: 创建自己的内容提供器
    android: 通过内容提供器读取系统联系人
    android: 内容提供器简介
    android: UriMatcher的用法
    java中static{}语句块详解
    android: SQLite 数据库的最佳实践
    android: SQLite使用 SQL 操作数据库
    android: SQLite查询数据
  • 原文地址:https://www.cnblogs.com/onlyRP/p/5167178.html
Copyright © 2011-2022 走看看