zoukankan      html  css  js  c++  java
  • HYSBZ 2243 染色

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2243

    题意:

    给定一棵有n个节点的无根树和m个操作,操作有2类:

    1、将节点a到节点b路径上所有点都染成颜色c;

    2、询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段),如“112221”3段组成:“11”、“222”和“1”

    思路:

    权值在点上的树链剖分+线段树成段更新+线段树成段询问。

    维护颜色端的数量方法:

    如果左儿子区间的最右端颜色与右儿子区间的最左端区间相同。

    sum[rt] = sum[rt<<1]+sum[rt<<1|1] - 1;

    否则sum[rt] = sum[rt<<1]+sum[rt<<1|1];

    树链剖分部分也进行相应维护。

     

      1 #include <iostream>
      2 #include <cstring>
      3 #include <string>
      4 #include <cstdio>
      5 #include <vector>
      6 using namespace std;
      7 int n, q;
      8 #define maxn 100010
      9 #define lson l, m, rt<<1
     10 #define rson m+1, r, rt<<1|1
     11 int siz[maxn], top[maxn], fa[maxn], son[maxn], dep[maxn];
     12 int w[maxn], fw[maxn];
     13 int A[maxn];
     14 vector <int> mp[maxn];
     15 int pos;
     16 int Left, Right;
     17 int sum[maxn<<2], cl[maxn<<2], cr[maxn<<2], col[maxn<<2];
     18 void PushUp(int rt)
     19 {
     20     if(cr[rt<<1] == cl[rt<<1|1]) sum[rt] = sum[rt<<1] + sum[rt<<1|1] - 1;
     21     else sum[rt] = sum[rt<<1] + sum[rt<<1|1];
     22     cl[rt] = cl[rt<<1];
     23     cr[rt] = cr[rt<<1|1];
     24 }
     25 void PushDown(int rt, int m)
     26 {
     27     if(col[rt] >= 0)
     28     {
     29         col[rt<<1] = col[rt<<1|1] = col[rt];
     30         sum[rt<<1] = sum[rt<<1|1] = 1;
     31         cl[rt<<1] = cl[rt<<1|1] = cr[rt<<1] = cr[rt<<1|1] = cl[rt];
     32         col[rt] = -1;
     33     }
     34 }
     35 void build(int l, int r, int rt)
     36 {
     37     col[rt] = -1;
     38     if(l == r)
     39     {
     40         cl[rt] = cr[rt] = A[fw[l]];
     41         sum[rt] = 1;
     42         return;
     43     }
     44     int m = (l+r)>>1;
     45     build(lson);
     46     build(rson);
     47     PushUp(rt);
     48 }
     49 void update(int L, int R, int c, int l, int r, int rt)
     50 {
     51     if(L <= l && R >= r)
     52     {
     53         col[rt] = c; sum[rt] = 1; cl[rt] = c; cr[rt] = c;
     54         return;
     55     }
     56     PushDown(rt, r-l+1);
     57     int m = (l+r)>>1;
     58     if(L <= m) update(L, R, c, lson);
     59     if(R > m) update(L, R, c, rson);
     60     PushUp(rt);
     61 }
     62 int query(int L, int R, int l, int r, int rt)
     63 {
     64     if(l == L) Left = cl[rt];
     65     if(r == R) Right = cr[rt];
     66     if(L <= l && R >= r)
     67     {
     68         return sum[rt];
     69     }
     70     PushDown(rt, r-l+1);
     71     int m = (l+r)>>1;
     72     int ret = 0;
     73     //合并线段树 这里也要修改!
     74     if(R <= m) return query(L, R, lson);
     75     else if(L > m) return query(L, R, rson);
     76     else
     77     {
     78         ret = query(L,R,lson) + query(L, R, rson);
     79         if(cl[rt<<1|1] == cr[rt<<1]) ret --;
     80         return ret;
     81     }
     82     //if(L <= m) ret += query(L, R, lson);
     83     //if(R > m) ret += query(L, R, rson);
     84 }
     85 int dfs1(int u, int pre, int deep)
     86 {
     87     siz[u] = 1; dep[u] = deep; fa[u] = pre;
     88     int mmax = 0;
     89     for(int i = 0; i < mp[u].size(); i++)
     90     {
     91         if(mp[u][i] != pre)
     92         {
     93             int temp = dfs1(mp[u][i], u, deep+1);
     94             siz[u] += temp;
     95             if(son[u] == -1 || temp >= mmax) 
     96             {
     97                 son[u] = mp[u][i];
     98                 mmax = temp;
     99             }
    100         }
    101     }
    102     return siz[u];
    103 }
    104 void dfs2(int u, int val)
    105 {
    106     top[u] = val;
    107     if(son[u] != -1)
    108     {
    109         w[u] = ++pos;
    110         fw[w[u]] = u;
    111         dfs2(son[u], val);
    112     }
    113     else if(son[u] == -1)
    114     {
    115         w[u] = ++pos;
    116         fw[w[u]] = u;
    117         return;
    118     }
    119     for(int i = 0; i < mp[u].size(); i++)
    120     {        
    121         if(mp[u][i] != son[u] && mp[u][i] != fa[u]) dfs2(mp[u][i], mp[u][i]);
    122     }
    123 }
    124 int find(int u, int v)
    125 {
    126     int mark1 = -1, mark2 = -1;
    127     int f1 = top[u], f2 = top[v];
    128     int temp = 0; int precolor = -1;
    129     while(f1 != f2)
    130     {
    131         if(dep[f1] < dep[f2])   //规定f1更深
    132         {
    133             swap(f1, f2);
    134             swap(u, v);
    135             swap(mark1, mark2);  //交替
    136         }
    137         temp += query(w[f1], w[u], 1, pos, 1);
    138         if(Right == mark1) temp --;
    139         mark1 = Left;
    140         u = fa[f1]; f1 = top[u];
    141     }
    142     if(dep[u] < dep[v])  //规定u更深
    143     {
    144         swap(u, v);
    145         swap(mark1, mark2);
    146     }
    147     temp += query(w[v], w[u], 1, pos, 1);
    148     if(Right == mark1) temp--;
    149     if(Left == mark2) temp--;
    150     return temp;
    151 }
    152 void UPDATE(int u, int v, int color)
    153 {
    154     int f1 = top[u], f2 = top[v];
    155     while(f1 != f2)
    156     {
    157         if(dep[f1] < dep[f2])
    158         {
    159             swap(f1, f2);
    160             swap(u, v);
    161         }
    162         update(w[f1], w[u], color, 1, pos, 1);
    163         u = fa[f1]; f1 = top[u];
    164     }
    165     if(dep[u] > dep[v]) swap(u, v);
    166     update(w[u], w[v], color, 1, pos, 1);
    167 }
    168 int main() 
    169 {
    170     //freopen("in.txt", "r", stdin);
    171     while(~scanf("%d%d", &n, &q))
    172     {
    173         for(int i = 1; i <= n; i++) mp[i].clear(); 
    174         pos = 0;
    175         memset(son, -1, sizeof(son));
    176         for(int i = 1; i <= n; i++) scanf("%d", &A[i]);
    177         for(int i = 1; i <= n-1; i++)
    178         {
    179             int a, b; scanf("%d%d", &a, &b);
    180             mp[a].push_back(b);
    181             mp[b].push_back(a);
    182         }
    183         dfs1(1, -1, 1);
    184         dfs2(1, 1);
    185         build(1, pos, 1);
    186         
    187         char op[5];
    188         while(q--)
    189         {
    190             scanf("%s", op);
    191             int a, b, c;
    192             if(op[0] == 'Q')
    193             {
    194                 scanf("%d%d", &a, &b);
    195                 printf("%d
    ", find(a, b));
    196             }
    197             else if(op[0] == 'C')
    198             {
    199                 scanf("%d%d%d", &a, &b, &c);
    200                 UPDATE(a, b, c);
    201             }
    202         }
    203     }
    204     return 0;
    205 }

     

     

  • 相关阅读:
    笔记:Struts2 的 JSON 插件
    笔记:Struts2 拦截器
    笔记:Struts2 文件上传和下载
    笔记:Struts2 文件上传和下载
    【学习总结】推荐系统-协同过滤原理
    【刷题】牛客网看到的鹅厂ML面筋-部分问题RecSys相关
    【刷题】【LeetCode】000-十大经典排序算法
    【刷题】【LeetCode】总
    【问题解决方案】pygame生成的窗口点右上角关闭按钮未响应问题的解决
    【刷题】若串 =’software’ ,其子串数目为:37
  • 原文地址:https://www.cnblogs.com/titicia/p/4902428.html
Copyright © 2011-2022 走看看