zoukankan      html  css  js  c++  java
  • [SDOI2017]树点涂色

    Problem

    三种操作

    • 1 x
      把点x到根节点的路径上所有的点染上一种没有用过的新颜色。

    • 2 x y
      求x到y的路径的权值。

    • 3 x
      在以x为根的子树中选择一个点,使得这个点到根节点的路径权值最大,求最大权值。

    显然挺板子的(LCT)啊 求个(LCA)套个线段树写一写。。
    这里求(LCA)用了树剖?鬼知道为什么我用了树剖。。

    // Isaunoya
    #include<bits/stdc++.h>
    using namespace std ;
    using LL = long long ;
    using uint = unsigned int ;
    #define int long long
    #define fir first
    #define sec second
    #define pb push_back
    #define mp(x , y) make_pair(x , y)
    template < typename T > inline void read(T & x) { x = 0 ; int f = 1 ; register char c = getchar() ;
      for( ; ! isdigit(c) ; c = getchar()) if(c == '-') f = -1 ;
      for( ; isdigit(c) ; c = getchar()) x = (x << 1) + (x << 3) + (c & 15) ;
      x *= f ;
    }
    template < typename T > inline void print(T x) {
      if(! x) { putchar('0') ; return ; }
      static int st[105] ;
      if(x < 0) putchar('-') , x = -x ;
      int tp = 0 ;
      while(x) st[++ tp] = x % 10 , x /= 10 ;
      while(tp) putchar(st[tp --] + '0') ;
    }
    template < typename T > inline void print(T x , char c) { print(x) ; putchar(c) ; }
    template < typename T , typename ...Args > inline void read(T & x , Args & ...args) { read(x) ; read(args...) ; }
    template < typename T > inline void sort( vector < T > & v) { sort(v.begin() , v.end()) ; return ; }
    template < typename T > inline void unique( vector < T > & v) { sort(v) ; v.erase(unique(v.begin() , v.end()) , v.end()) ; }
    template < typename T > inline void cmax(T & x , T y) { if(x < y) x = y ; return ; }
    template < typename T > inline void cmin(T & x , T y) { if(x > y) x = y ; return ; }
    const int Mod = LLONG_MAX ;
    inline int QP(int x , int y) { int ans = 1 ;
      for( ; y ; y >>= 1 , x = (x * x) % Mod)
        if(y & 1) ans = (ans * x) % Mod ;
      return ans ;
    }
    template < typename T > inline T gcd(T x , T y) { if(y == 0) return x ; return gcd(y , x % y) ; }
    template < typename T > inline T lcm(T x , T y) { return x * y / gcd(x , y) ; }
    template < typename T > inline void mul(T & x , T y) { x = 1LL * x * y ; if(x >= Mod) x %= Mod ; }
    template < typename T > inline void add(T & x , T y) { if((x += y) >= Mod) x -= Mod ; }
    template < typename T > inline void sub(T & x , T y) { if((x -= y) < 0) x += Mod ; }
    int n , m ;
    const int N = 1e5 + 5 ;
    int d[N] , rev[N] ; int tot = 0 ;
    int L[N << 2] , R[N << 2] ;
    int tag[N << 2] ; int mx[N << 2] ;
    inline void pushdown(int x) { if(! tag[x]) return ;
      tag[x << 1] += tag[x] ; tag[x << 1 | 1] += tag[x] ;
      mx[x << 1] += tag[x] ; mx[x << 1 | 1] += tag[x] ; tag[x] = 0 ;
    }
    inline void build(int  l , int r , int rt) { if(l == r) { mx[rt] = d[rev[l]] ; return ; } int mid = l + r >> 1 ;
      build(l , mid , rt << 1) ; build(mid + 1 , r , rt << 1 | 1) ; mx[rt] = max(mx[rt << 1] , mx[rt << 1 | 1]) ;
    }
    inline void update(int a , int b , int l , int r , int rt , int val) {
      if(a <= l && r <= b) { tag[rt] += val ; mx[rt] += val ; return ; }
      pushdown(rt) ; int mid = l + r >> 1 ;
      if(a <= mid) update(a , b , l , mid , rt << 1 , val) ;
      if(b > mid) update(a , b , mid + 1 , r , rt << 1 | 1 , val) ;
      mx[rt] = max(mx[rt << 1] , mx[rt << 1 | 1]) ;
    }
    inline int query(int a , int b , int l , int r , int rt) {
      if(a <= l && r <= b) return mx[rt] ; pushdown(rt) ;
      int mid = l + r >> 1  ; int ans = 0 ;
      if(a <= mid) cmax(ans , query(a , b , l , mid , rt << 1)) ;
      if(b > mid) cmax(ans , query(a , b , mid + 1 , r , rt << 1 | 1)) ;
      return ans ;
    }
    class LCT {
    public : int rev[N] ; int fa[N] ; int ch[N][2] ;
    #define ls(x) ch[x][0]
    #define rs(x) ch[x][1]
      inline bool isroot(int x) { return ls(fa[x]) != x && rs(fa[x]) != x ; }
      inline bool getr(int x) { return rs(fa[x]) == x ; }
      inline void pushr(int x) { if(! rev[x]) return ; swap(ls(x) , rs(x)) ; rev[ls(x)] ^= 1 ; rev[rs(x)] ^= 1 ; rev[x] ^= 1 ; }
      inline void rotate(int x) { int y = fa[x] , z = fa[y] ; int k = getr(x) ;
        if(! isroot(y)) ch[z][getr(y)] = x ; fa[x] = z ; ch[y][k] = ch[x][k ^ 1] ; fa[ch[x][k ^ 1]] = y ; ch[x][k ^ 1] = y ; fa[y] = x ;
      }
      inline void pushall(int x) { if(! isroot(x)) pushall(fa[x]) ; pushr(x) ;}
      inline void splay(int x) { pushall(x) ; while(! isroot(x)) { int y = fa[x] ; if(! isroot(y)) rotate(getr(x) ^ getr(y) ? x : y) ; rotate(x) ; } }
      inline int findroot(int x) {
        while(ls(x)) x = ls(x) ; return x ;
      }
      inline void access(int x) { int son = 0 ;
        for( int tp = 0 ; x ; tp = x , x = fa[tp]) { splay(x) ;
          if(rs(x)) son = findroot(rs(x)) , update(L[son] , R[son] , 1 , n , 1 , 1) ;
          if(rs(x) = tp) { son = findroot(tp) ; update(L[son] , R[son] , 1 , n , 1 , - 1) ; }
          rs(x) = tp ;
        }
      }
    } lct ;
    struct node { int v , nxt ; } e[N << 1] ;
    int head[N] , cnt = 0 ;
    inline void add(int u , int v) { e[++ cnt].v = v ; e[cnt].nxt = head[u] ; head[u] = cnt ; }
    int fa[N] ; int size[N] ; int son[N] ;
    inline void Dfs(int u) { size[u] = 1 ; L[u] = ++ tot ; rev[tot] = u ;
      for(register int i = head[u] ; i ; i = e[i].nxt) {
        int v = e[i].v ; if(v == fa[u]) continue ;
        fa[v] = lct.fa[v] = u ; d[v] = d[u] + 1 ; Dfs(v) ; size[u] += size[v] ;
        if(size[v] > size[son[u]]) son[u] = v ;
      } R[u] = tot ;
    }
    int top[N] ;
    inline void Dfs2(int u , int tp) { top[u] = tp ;
      if(! son[u]) return ; Dfs2(son[u] , tp) ;
      for(register int i = head[u] ; i ; i = e[i].nxt) { int v = e[i].v ;
        if(v == fa[u] || v == son[u]) continue ; Dfs2(v , v) ;
      }
    }
    inline int lca(int x , int y) { int fx = top[x] , fy = top[y] ;
      while(fx ^ fy) { if(d[fx] < d[fy]) swap(x , y) , swap(fx , fy) ; x = fa[fx] , fx = top[x] ; }
      if(d[x] > d[y]) swap(x , y) ;
      return x ;
    }
    signed main() { read(n , m) ;
      for(register int i = 1 ; i <= n - 1 ; i ++) { int u , v ; read(u , v) ; add(u , v) ; add(v , u) ;}
      d[1] = 1 ; Dfs(1) , Dfs2(1 , 1) ; build(1 , n , 1) ;
      for(register int i = 1 ; i <= m ; i ++) { int opt , x , y ; read(opt) ;
        if(opt == 1) { read(x) ; lct.access(x) ; }
        if(opt == 2) { read(x , y) ; int Lca = lca(x , y) ;
          int ans = query(L[x] , L[x] , 1 , n , 1) ; int ans2 = query(L[y] , L[y] , 1 , n , 1) ; int ans3 = query(L[Lca] , L[Lca] , 1 , n , 1) ;
          print(ans + ans2 - 2 * ans3 + 1 , '
    ') ;
        }
        if(opt == 3) { read(x) ; int ans = query(L[x] , R[x] , 1 , n , 1) ; print(ans , '
    ') ; }
      }
      return 0 ;
    }
    
  • 相关阅读:
    爬取校园新闻首页的新闻的详情,使用正则表达式,函数抽离
    网络爬虫基础练习
    Mysql 使用 select into outfile
    Mysql 使用CMD 登陆
    使用Clean() 去掉由函数自动生成的字符串中的双引号
    Get Resultset from Oracle Stored procedure
    获取引用某个主键的所有外键的表
    Entity Framework 丢失数据链接的绑定,在已绑好的EDMX中提示“Choose Your Data Connection”
    添加MySql Metat Database 信息
    at System.Data.EntityClient.EntityConnection.GetFactory(String providerString)
  • 原文地址:https://www.cnblogs.com/Isaunoya/p/11716668.html
Copyright © 2011-2022 走看看