zoukankan      html  css  js  c++  java
  • BZOJ2243 [SDOI2011]染色

    恩恩树链剖分一下

    于是用线段树维护每一个子段的颜色信息 --不同颜色段数,因为要合并所以还要维护每一段的左右端点颜色信息

    然后就没有然后了2333

    尝试着写了个指针版的。。。感觉还可以啊

    话说,是不是写多棵线段树会快啊?

      1 /**************************************************************
      2     Problem: 2243
      3     User: rausen
      4     Language: C++
      5     Result: Accepted
      6     Time:4176 ms
      7     Memory:31324 kb
      8 ****************************************************************/
      9  
     10 #include <cstdio>
     11 #include <algorithm>
     12  
     13 using namespace std;
     14 const int N = 100005;
     15 const int M = N << 2;
     16 const int Maxlen = N * 75;
     17  
     18 char buf[Maxlen], *C = buf;
     19 int Len;
     20  
     21 struct edge {
     22     int next, to;
     23     edge() {}
     24     edge(int _n, int _t) : next(_n), to(_t) {}
     25 } e[N << 1];
     26  
     27 int first[N], tot;
     28  
     29 struct tree_node {
     30     int sz, dep, fa, son, top, w;
     31 } tr[N];
     32  
     33 int cnt_tree;
     34  
     35 struct seg_node {
     36     seg_node *lson, *rson;
     37     int l, r, sz, tag, lc, rc;
     38      
     39     inline void fill(int _s, int _t) {
     40         sz = _s;
     41         tag = _t, lc = _t, rc = _t;
     42     }
     43 } *root, mempool[M], *cnt_seg = mempool;
     44  
     45 int n, Q, c[N];
     46  
     47 inline int read() {
     48     int x = 0;
     49     while (*C < '0' || '9' < *C) ++C;
     50     while ('0' <= *C && *C <= '9')
     51         x = x * 10 + *C - '0', ++C;
     52     return x;
     53 }
     54  
     55 inline void Add_Edges(int x, int y) {
     56     e[++tot] = edge(first[x], y), first[x] = tot;
     57     e[++tot] = edge(first[y], x), first[y] = tot;
     58 }
     59  
     60  
     61 void dfs(int p) {
     62     int x, y;
     63     tr[p].sz = 1;
     64     for (x = first[p]; x; x = e[x].next)
     65         if ((y = e[x].to) != tr[p].fa) {
     66             tr[y].dep = tr[p].dep + 1, tr[y].fa = p;
     67             dfs(y);
     68             tr[p].sz += tr[y].sz;
     69             if (!tr[p].son || tr[tr[p].son].sz < tr[y].sz)
     70                 tr[p].son = y;
     71         }
     72 }
     73  
     74 void DFS(int p) {
     75     tr[p].w = ++cnt_tree;
     76     if (!tr[p].son) return;
     77     tr[tr[p].son].top = tr[p].top;
     78     DFS(tr[p].son);
     79     int x, y;
     80     for (x = first[p]; x; x = e[x].next)
     81         if ((y = e[x].to) != tr[p].fa && y != tr[p].son) {
     82             tr[y].top = y;
     83             DFS(y);
     84         }
     85 }
     86  
     87  
     88 #define L p -> l
     89 #define R p -> r
     90 #define Lc p -> lc
     91 #define Rc p -> rc
     92 #define Sz p -> sz
     93 #define Tag p -> tag
     94 #define Lson p -> lson
     95 #define Rson p -> rson
     96 #define mid (l + r >> 1)
     97 void seg_build(seg_node *&p, int l, int r) {
     98     p = ++cnt_seg;
     99     L = l, R = r, Sz = 1, Tag = -1;
    100     if (l == r) return;
    101     seg_build(Lson, l, mid), seg_build(Rson, mid + 1, r);
    102 }
    103 #undef mid
    104  
    105 inline void seg_push_up(seg_node *p) {
    106     Lc = Lson -> lc, Rc = Rson -> rc;
    107     Sz = Lson -> sz + Rson -> sz;
    108     if (Lson -> rc == Rson -> lc) Sz -= 1;
    109 }
    110  
    111 inline void seg_push_down(seg_node *p) {
    112     if (Tag == -1 || L == R) {
    113         Tag = -1;
    114         return;
    115     }
    116     (*Lson).fill(1, Tag);
    117     (*Rson).fill(1, Tag);
    118     Tag = -1;
    119 }
    120  
    121 #define mid (L + R >> 1)
    122 void seg_update(seg_node *p, int l, int r, int c) {
    123     seg_push_down(p);
    124     if (l == L && R == r) {
    125         (*p).fill(1, c);
    126         return;
    127     }
    128     if (r <= mid) seg_update(Lson, l, r, c);
    129     else if (mid < l) seg_update(Rson, l, r, c);
    130     else {
    131         seg_update(Lson, l, mid, c);
    132         seg_update(Rson, mid + 1, r, c);
    133     }
    134     seg_push_up(p);
    135 }
    136  
    137 int seg_query_cnt(seg_node *p, int l, int r) {
    138     seg_push_down(p);
    139     if (l == L && R == r) return Sz;
    140     if (r <= mid) return seg_query_cnt(Lson, l, r);
    141     else if (mid < l) return seg_query_cnt(Rson, l, r);
    142     else {
    143         return seg_query_cnt(Lson, l, mid) + seg_query_cnt(Rson, mid + 1, r) -
    144             (Lson -> rc == Rson -> lc);
    145     }
    146 }
    147  
    148 int seg_query_color(seg_node *p, int pos) {
    149     seg_push_down(p);
    150     if (L == R) return Lc;
    151     if (pos <= mid) return seg_query_color(Lson, pos);
    152     else return seg_query_color(Rson, pos);
    153 }
    154 #undef mid
    155  
    156  
    157 void work_change(int x, int y, int c) {
    158     while (tr[x].top != tr[y].top) {
    159         if (tr[tr[x].top].dep < tr[tr[y].top].dep)
    160             swap(x, y);
    161         seg_update(root, tr[tr[x].top].w, tr[x].w, c);
    162         x = tr[tr[x].top].fa;
    163     }
    164     if (tr[x].dep < tr[y].dep)
    165         swap(x, y);
    166     seg_update(root, tr[y].w, tr[x].w, c);
    167 }
    168  
    169 int work_sum(int x, int y) {
    170     int res = 0;
    171     while (tr[x].top != tr[y].top) {
    172         if (tr[tr[x].top].dep < tr[tr[y].top].dep)
    173             swap(x, y);
    174         res += seg_query_cnt(root, tr[tr[x].top].w, tr[x].w);
    175         x = tr[x].top;
    176         if (seg_query_color(root, tr[x].w) == seg_query_color(root, tr[tr[x].fa].w))
    177             --res;
    178         x = tr[x].fa;
    179     }
    180     if (tr[x].dep < tr[y].dep)
    181         swap(x, y);
    182     res += seg_query_cnt(root, tr[y].w, tr[x].w);
    183     return res;
    184 }
    185  
    186 inline void work() {
    187     int x, y, z;
    188     while (*C != 'C' && *C != 'Q') ++C;
    189     if (*C == 'Q') {
    190         x = read(), y = read();
    191         printf("%d
    ", work_sum(x, y));
    192     } else {
    193         x = read(), y = read(), z = read();
    194         work_change(x, y, z);
    195     }
    196 }
    197  
    198 void build() {
    199     int i;
    200     for (i = 1; i <= n; ++i)
    201         c[i] = read();
    202     for (i = 1; i < n; ++i)
    203         Add_Edges(read(), read());
    204     tr[1].fa = -1;
    205     dfs(1);
    206     DFS(1);
    207     seg_build(root, 1, n);
    208     for (i = 1; i <= n; ++i)
    209         seg_update(root, tr[i].w, tr[i].w, c[i]);
    210 }
    211  
    212 int main() {
    213     Len = fread(C , 1, Maxlen, stdin);
    214     buf[Len] = '';
    215     n = read(), Q = read();
    216     build();
    217     while (Q--) 
    218         work();
    219     return 0;
    220 }
    View Code
    By Xs酱~ 转载请说明 博客地址:http://www.cnblogs.com/rausen
  • 相关阅读:
    【mybatis-SqlSession的方法总结】
    【项目中遇到的一点问题】
    【request获取用户请求ip】
    【Linux入门】
    【linux学习-centeros】
    java Map 映射
    Java Set接口
    Java 泛型
    Java集合框架---重构设计
    Java 数据结构之双链表
  • 原文地址:https://www.cnblogs.com/rausen/p/4189267.html
Copyright © 2011-2022 走看看