• [SDOI2011]染色


    嘟嘟嘟

    一看就知道是一道树剖题。

    先树剖转换成线性,然后线段树维护。

    维护的时候跟酒店那道题有点像,但比那个简单多了。

    首先一个sum代表颜色段数量,然后除了lazy之外还有lco,rco分别代表区间左右端点是啥颜色。

    合并的时候除了sum[now] = sum[now <<1] + sum[now << 1 |1]外,还要考虑左右子区间靠在一起的地方颜色是否相等,即rco[now << 1] == lco[now << 1 | 1],是的话就要减一。

    查询的时候需要注意链的顶端的父亲结点和链的顶端结点颜色是否相同,是的话答案还是要--。这个单独写一个线段树单点查询的函数就行,很短。

    p.s.emacs的格式就是丑,凑合着看吧

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<algorithm>
      4 #include<cstring>
      5 #include<cmath>
      6 #include<cstdlib>
      7 #include<cctype>
      8 #include<stack>
      9 #include<queue>
     10 #include<vector>
     11 using namespace std;
     12 #define enter puts("")
     13 #define space putchar(' ')
     14 #define Mem(a, x) memset(a, x, sizeof(a))
     15 #define rg register
     16 typedef long long ll;
     17 typedef double db;
     18 const int INF = 0x3f3f3f3f;
     19 const db eps = 1e-8;
     20 const int maxn = 1e5 + 5;
     21 inline ll read()
     22 {
     23   ll ans = 0;
     24   char ch = getchar(), las = ' ';
     25   while(!isdigit(ch)) las = ch, ch = getchar();
     26   while(isdigit(ch)) ans = (ans << 3) + (ans << 1) + ch - '0', ch = getchar();
     27   if(las == '-') ans = -ans;
     28   return ans;
     29 }
     30 inline void write(ll x)
     31 {
     32   if(x < 0) putchar('-'), x = -x;
     33   if(x >= 10) write(x / 10);
     34   putchar(x % 10 + '0');
     35 }
     36 
     37 int n, m, a[maxn];
     38 vector<int> v[maxn];
     39 
     40 bool vis[maxn];
     41 int dep[maxn], fa[maxn], siz[maxn], son[maxn];
     42 void dfs1(int now)
     43 {
     44   vis[now] = 1; siz[now] = 1;
     45   for(int i = 0; i < (int)v[now].size(); ++i)
     46     {
     47       if(!vis[v[now][i]])
     48     {
     49       dep[v[now][i]] = dep[now] + 1;
     50       fa[v[now][i]] = now;
     51       dfs1(v[now][i]);
     52       siz[now] += siz[v[now][i]];
     53       if(!son[now] || siz[son[now]] < siz[v[now][i]]) son[now] = v[now][i];
     54     }
     55     }
     56 }
     57 int dfsx[maxn], pos[maxn], top[maxn], cnt = 0;
     58 void dfs2(int now)
     59 {
     60   dfsx[now] = ++cnt; pos[cnt] = now;
     61   vis[now] = 1;
     62   if(son[now])
     63     {
     64       top[son[now]] = top[now];
     65       dfs2(son[now]);
     66     }
     67   for(int i = 0; i < (int)v[now].size(); ++i)
     68     {
     69       if(!vis[v[now][i]] && v[now][i] != son[now])
     70     {
     71       top[v[now][i]] = v[now][i];
     72       dfs2(v[now][i]);
     73     }
     74     }
     75 }
     76 
     77 struct Tree
     78 {
     79   int l, r;
     80   int sum, lco, rco, lzy;
     81   Tree operator + (const Tree& other)const
     82   {
     83     Tree ret;
     84     ret.l = l; ret.r = other.r;
     85     ret.lzy = -1;
     86     ret.sum = sum + other.sum;
     87     if(rco == other.lco) ret.sum--;
     88     ret.lco = lco; ret.rco = other.rco;
     89     return ret;
     90   }
     91 }t[maxn << 2];
     92 
     93 void build(int L, int R, int now)
     94 {
     95   t[now].l = L; t[now].r = R;
     96   t[now].lzy = -1;
     97   if(L == R)
     98     {
     99       t[now].sum = 1;
    100       t[now].lco = t[now].rco = a[pos[L]];
    101       return;
    102     }
    103   int mid = (L + R) >> 1;
    104   build(L, mid, now << 1);
    105   build(mid + 1, R, now << 1 | 1);
    106   t[now] = t[now << 1] + t[now << 1 | 1];
    107 }
    108 void pushdown(int now)
    109 {
    110   if(t[now].lzy != -1)
    111     {
    112       t[now << 1].sum = t[now << 1 | 1].sum = 1;
    113       t[now << 1].lzy = t[now << 1 | 1].lzy = t[now].lzy;
    114       t[now << 1].lco = t[now << 1].rco = t[now].lzy;
    115       t[now << 1 | 1].lco = t[now << 1 | 1].rco = t[now].lzy;
    116       t[now].lzy = -1;
    117     }
    118 }
    119 void update(int L, int R, int now, int d)
    120 {
    121   if(L == t[now].l && R == t[now].r)
    122     {
    123       t[now].sum = 1;
    124       t[now].lco = t[now].rco = d;
    125       t[now].lzy = d; return;
    126     }
    127   pushdown(now);
    128   int mid = (t[now].l + t[now].r) >> 1;
    129   if(R <= mid) update(L, R, now << 1, d);
    130   else if(L > mid) update(L, R, now << 1 | 1, d);
    131   else update(L, mid, now << 1, d), update(mid + 1, R, now << 1 | 1, d);
    132   t[now] = t[now << 1] + t[now << 1 | 1];
    133 }
    134 int query(int L, int R, int now)
    135 {
    136   if(L == t[now].l && R == t[now].r) return t[now].sum;
    137   pushdown(now);
    138   int mid = (t[now].l + t[now].r) >> 1;
    139   if(R <= mid) return query(L, R, now << 1);
    140   else if(L > mid) return query(L, R, now << 1 | 1);
    141   else
    142     {
    143       int ret = query(L, mid, now << 1) + query(mid + 1, R, now << 1 | 1);
    144       if(t[now << 1].rco == t[now << 1 | 1].lco) ret--;
    145       return ret;
    146     }
    147 }
    148 int query_col(int x, int now)
    149 {
    150     if(t[now].l == t[now].r) return t[now].lco;
    151     pushdown(now);
    152     int mid = (t[now].l + t[now].r) >> 1;
    153     if(x <= mid) return query_col(x, now << 1);
    154     else return query_col(x, now << 1 | 1);
    155 }
    156 
    157 void update_path(int x, int y, int d)
    158 {
    159   while(top[x] != top[y])
    160   {
    161       if(dep[top[x]] < dep[top[y]]) swap(x, y);
    162       update(dfsx[top[x]], dfsx[x], 1, d);
    163       x = fa[top[x]];
    164   }
    165   if(dep[x] > dep[y]) swap(x, y);
    166   update(dfsx[x], dfsx[y], 1, d);
    167 }
    168 int query_path(int x, int y)
    169 {
    170     int ret = 0;
    171     while(top[x] != top[y])
    172     {
    173           if(dep[top[x]] < dep[top[y]]) swap(x, y);    
    174           ret += query(dfsx[top[x]], dfsx[x], 1);
    175           if(query_col(dfsx[top[x]], 1) == query_col(dfsx[fa[top[x]]], 1)) ret--;
    176           x = fa[top[x]];
    177     }
    178     if(dep[x] > dep[y]) swap(x, y);
    179     ret += query(dfsx[x], dfsx[y], 1);
    180     return ret;
    181 }
    182   
    183 char c[2];  
    184   
    185 int main()
    186 {
    187   n = read(); m = read();
    188   for(int i = 1; i <= n; ++i) a[i] = read();
    189   for(int i = 1; i < n; ++i)
    190     {
    191       int x = read(), y = read();
    192       v[x].push_back(y); v[y].push_back(x);
    193     }
    194   dfs1(1); Mem(vis, 0);
    195   top[1] = 1; dfs2(1);
    196   build(1, cnt, 1);
    197   for(int i = 1; i <= m; ++i)
    198     {
    199       scanf("%s", c); int L = read(), R = read();
    200       if(c[0] == 'C')
    201     {
    202       int x = read();
    203       update_path(L, R, x);
    204     }
    205       else write(query_path(L, R)), enter;
    206     }
    207   return 0;
    208 }
    View Code
  • 相关阅读:
    K3Cloud 解决方案版本号问题
    K3Cloud 通过元数据查询单据信息
    K3Cloud 设置分录的字段颜色
    K3Cloud 干预标准产品插件
    K3Cloud 根据单据ID 获取单据视图和数据包
    K3Cloud 后台修改账户密码策略
    K3Cloud 选择基础资料允许显示未审核数据
    K3Cloud 根据内码和基础资料元数据获取基础资料数据包
    按照应用场景划分安全测试
    常见业务场景的安全测试及安全开发
  • 原文地址:https://www.cnblogs.com/mrclr/p/9710529.html
Copyright © 2020-2023  润新知