zoukankan      html  css  js  c++  java
  • bzoj4551: [Tjoi2016&Heoi2016]树(树链剖分)

    4551: [Tjoi2016&Heoi2016]树

    题目:传送门 


    题解:

       一道树剖裸题

       线段树的c值维护新编号最大的已被标记的节点。

       用一个数组转化新编号为旧编号(就是因为这个小细节打错ORZ)

       然后就是一顿乱撸

        


    代码:

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<cstdlib>
      4 #include<cmath>
      5 #include<algorithm>
      6 #define N 110000
      7 using namespace std;
      8 struct node
      9 {
     10     int x,y,next;
     11 }a[N*2];int len,last[N];
     12 void ins(int x,int y)
     13 {
     14     len++;a[len].x=x;a[len].y=y;
     15     a[len].next=last[x];last[x]=len;
     16 }
     17 struct trnode
     18 {
     19     int l,r,c,lc,rc;
     20 }tr[N*2];int trlen;
     21 void bt(int l,int r)
     22 {
     23     int now=++trlen;
     24     tr[now].l=l;tr[now].r=r;tr[now].c=-1;
     25     tr[now].lc=tr[now].rc=-1;
     26     if(l<r)
     27     {
     28         int mid=(l+r)/2;
     29         tr[now].lc=trlen+1;bt(l,mid);
     30         tr[now].rc=trlen+1;bt(mid+1,r);
     31     }
     32 }
     33 int dep[N],tot[N],ys[N],son[N],fa[N],top[N],id[N],z;
     34 void pre_tree_node(int x)
     35 {
     36     tot[x]=1;son[x]=0;
     37     for(int k=last[x];k;k=a[k].next)
     38     {
     39         int y=a[k].y;
     40         if(y!=fa[x])
     41         {
     42             fa[y]=x;
     43             dep[y]=dep[x]+1;
     44             pre_tree_node(y);
     45             tot[x]+=tot[y];
     46             if(tot[y]>tot[son[x]])son[x]=y;
     47         }
     48     }
     49 }
     50 void pre_tree_edge(int x,int tp)
     51 {
     52     ys[x]=++z;top[x]=tp;id[z]=x;
     53     if(son[x]!=0)pre_tree_edge(son[x],tp);
     54     for(int k=last[x];k;k=a[k].next)
     55     {
     56         int y=a[k].y;
     57         if(y!=fa[x] && y!=son[x])
     58             pre_tree_edge(y,y);
     59     }
     60 }
     61 void change(int now,int x)
     62 {
     63     if(tr[now].l==tr[now].r){tr[now].c=x;return ;}
     64     int lc=tr[now].lc,rc=tr[now].rc,mid=(tr[now].l+tr[now].r)/2;
     65     if(x<=mid)change(lc,x);
     66     else change(rc,x);
     67     tr[now].c=max(tr[lc].c,tr[rc].c);
     68 }
     69 int find_x(int now,int l,int r)
     70 {
     71     if(tr[now].l==l&&tr[now].r==r)return tr[now].c;
     72     int lc=tr[now].lc,rc=tr[now].rc,mid=(tr[now].l+tr[now].r)/2;
     73     if(r<=mid)return find_x(lc,l,r);
     74     else if(l>mid)return find_x(rc,l,r);
     75     else return max(find_x(lc,l,mid),find_x(rc,mid+1,r));
     76 }
     77 int get_id(int x)
     78 {
     79     int T=top[x];
     80     while(1)
     81     {
     82         int k=find_x(1,ys[T],ys[x]);
     83         if(k==-1)
     84         {
     85             x=fa[T];
     86             T=top[x];
     87         }
     88         else return id[k];
     89     }
     90 }
     91 char s[5];
     92 int main()
     93 {
     94     int n,m;
     95     scanf("%d%d",&n,&m);
     96     for(int i=1;i<n;i++)
     97     {
     98         int x,y;
     99         scanf("%d%d",&x,&y);
    100         ins(x,y);
    101     }
    102     dep[1]=0;fa[1]=0;pre_tree_node(1);z=0;pre_tree_edge(1,1);trlen=0;bt(1,z);change(1,ys[1]);
    103     while(m--)
    104     {
    105         int x;
    106         scanf("%s%d",s+1,&x);
    107         if(s[1]=='Q')printf("%d
    ",get_id(x));
    108         else change(1,ys[x]);
    109     }
    110     return 0;
    111 }
  • 相关阅读:
    php详解和优化
    接口
    抽象类
    对象转型
    面向对象2
    Super关键字
    Object类介绍
    有效处理java异常的三个原则
    this关键字
    equals方法
  • 原文地址:https://www.cnblogs.com/CHerish_OI/p/8650031.html
Copyright © 2011-2022 走看看