zoukankan      html  css  js  c++  java
  • 【SDOI2011】染色

    Description

    给定一棵树和若干操作,每次可以选取树上任意两点之间的路径染成一种颜色,或是查询任意两点之间路径上有多少段颜色。

    Solution

    树链剖分不解释,主要分析线段树的维护,在线段树区间上我们维护区间左端的颜色、右端的颜色、整个区间颜色段的数量。那么当我们合并两个区间时,我们首先将两区间的颜色段数量相加,如果左区间右端的颜色等于右区间左端的颜色,那么答案减一。

    剩下的就是线段树和树链剖分的基本操作,在此不再赘述。

    Code

      1 #include <iostream>
      2 #include <cstdio>
      3 using namespace std;
      4 typedef long long ll;
      5 inline int read() {
      6     int ret = 0, op = 1;
      7     char c = getchar();
      8     while (c < '0' || c > '9') {
      9         if (c == '-') op = -1; 
     10         c = getchar();
     11     }
     12     while (c <= '9' && c >= '0') {
     13         ret = ret * 10 + c - '0';
     14         c = getchar();
     15     }
     16     return ret * op;
     17 }
     18 struct node {
     19     int next, to;
     20 } a[100010 << 1];
     21 struct segment {
     22     int lc, rc, cnt;
     23     int tag;
     24 } s[100010 << 2];
     25 int n, m, num, head[100010], in[100010];
     26 void add(int from, int to) {
     27     a[++num].next = head[from];
     28     a[num].to = to;
     29     head[from] = num;
     30 }
     31 int size[100010], top[100010], son[100010], dep[100010], f[100010];
     32 int seg[100010 << 2], rev[100010 << 2], tot;
     33 void dfs1(int u, int fa) {
     34     dep[u] = dep[fa] + 1;
     35     f[u] = fa;
     36     size[u] = 1;
     37     for (int i = head[u]; i; i = a[i].next)
     38         if (a[i].to != fa) {
     39             dfs1(a[i].to, u);
     40             size[u] += size[a[i].to];
     41             if (size[son[u]] < size[a[i].to]) son[u] = a[i].to;
     42         }
     43     return ;
     44 }
     45 void dfs2(int u, int fa) {
     46     if (son[u]) {
     47         top[son[u]] = top[u];
     48         seg[son[u]] = ++tot;
     49         rev[tot] = son[u];
     50         dfs2(son[u], u);
     51     }
     52     for (int i = head[u]; i; i = a[i].next)
     53         if (!top[a[i].to]) {
     54             top[a[i].to] = a[i].to;
     55             seg[a[i].to] = ++tot;
     56             rev[tot] = a[i].to;
     57             dfs2(a[i].to, a[i].to);
     58         }
     59 }
     60 void pushup(int now) {
     61     s[now].lc = s[now << 1].lc;
     62     s[now].rc = s[now << 1 | 1].rc;
     63     s[now].cnt = s[now << 1].cnt + s[now << 1 | 1].cnt;
     64     if (s[now << 1].rc == s[now << 1 | 1].lc) s[now].cnt --;
     65 }
     66 void pushdown(int now) {
     67     if (s[now].tag != -1) {
     68         s[now << 1].lc = s[now << 1].rc = s[now << 1 | 1].lc = s[now << 1 | 1].rc = s[now].tag;
     69         s[now << 1].cnt = s[now << 1 | 1].cnt = 1;
     70         s[now << 1].tag = s[now << 1 | 1].tag = s[now].tag;
     71         s[now].tag = -1;
     72     }
     73 }
     74 void build(int now, int l, int r) {
     75     s[now].tag = -1;
     76     if (l == r) {
     77         s[now].lc = s[now].rc = in[rev[l]];
     78         s[now].cnt = 1;
     79         return ;
     80     } 
     81     int mid = l + r >> 1;
     82     build(now << 1, l, mid);
     83     build(now << 1 | 1, mid + 1, r);
     84     pushup(now);
     85     return ;
     86 }
     87 void update(int now, int l, int r, int x, int y, int val) {
     88     if (x == l && r == y) {
     89         s[now].lc = s[now].rc = s[now].tag = val;
     90         s[now].cnt = 1;
     91         return ;
     92     }
     93     int mid = l + r >> 1;
     94     pushdown(now);
     95     if (y <= mid) update(now << 1, l, mid, x, y, val);
     96     else if (x > mid) update(now << 1 | 1, mid + 1, r, x, y, val);
     97     else {
     98         update(now << 1, l, mid, x, mid, val);
     99         update(now << 1 | 1, mid + 1, r, mid + 1, y, val);
    100     }
    101     pushup(now);
    102     return ;
    103 }
    104 void find(int x, int y, int val) {
    105     while (top[x] != top[y]) {
    106         if (dep[top[x]] < dep[top[y]]) swap(x, y);
    107         update(1, 1, tot, seg[top[x]], seg[x], val);
    108         x = f[top[x]];
    109     }
    110     if (dep[x] > dep[y]) swap(x, y);
    111     update(1, 1, tot, seg[x], seg[y], val);
    112 }
    113 int query(int now, int l, int r, int x, int y) {
    114     if (x == l && r == y) return s[now].cnt;
    115     pushdown(now);
    116     int mid = l + r >> 1;
    117     if (y <= mid) return query(now << 1, l, mid, x, y);
    118     else if (x > mid) return query(now << 1 | 1, mid + 1, r, x, y);
    119     else {
    120         int retl = query(now << 1, l, mid, x, mid);
    121         int retr = query(now << 1 | 1, mid + 1, r, mid + 1, y);
    122         int ret = retl + retr;
    123         if (s[now << 1].rc == s[now << 1 | 1].lc) ret--;
    124         return ret;
    125     }
    126 }
    127 int query(int now, int l, int r, int x) {
    128     if (l == r) return s[now].lc;
    129     int mid = l + r >> 1;
    130     pushdown(now);
    131     if (x <= mid) return query(now << 1, l, mid, x);
    132     else return query(now << 1 | 1, mid + 1, r, x);
    133 }
    134 int find(int x, int y) {
    135     int ans = 0;
    136     while (top[x] != top[y]) {
    137         if (dep[top[x]] < dep[top[y]]) swap(x, y);
    138         ans += query(1, 1, tot, seg[top[x]], seg[x]);
    139         if (query(1, 1, tot, seg[top[x]]) == query(1, 1, tot, seg[f[top[x]]])) ans--;
    140         x = f[top[x]];
    141         // cout << ans << endl;
    142     }
    143     if (dep[x] > dep[y]) swap(x, y);
    144     ans += query(1, 1, tot, seg[x], seg[y]);
    145     // cout << ans << endl;
    146     return ans;
    147 }
    148 int main() {
    149     n = read(); m = read();
    150     for (int i = 1; i <= n; ++i) in[i] = read();
    151     for (int i = 1; i < n; ++i) {
    152         int x = read(), y = read();
    153         add(x, y); add(y, x);
    154     }
    155     dfs1(1, 0);
    156     seg[1] = tot = 1;
    157     rev[1] = 1;
    158     top[1] = 1;
    159     dfs2(1, 1);
    160     build(1, 1, tot);
    161     while (m--) {
    162         char op;
    163         int x, y, z;
    164         cin >> op;
    165         cin >> x >> y;
    166         if (op == 'C') {
    167             cin >> z;
    168             find(x, y, z);
    169         }
    170         else {
    171             printf("%d
    ", find(x, y));
    172         }
    173     }
    174     return 0;
    175 }
    AC Code
  • 相关阅读:
    判断窗体 show完成
    【洛谷1349】广义斐波那契数列
    【洛谷2744 】【CJOJ1804】[USACO5.3]量取牛奶Milk Measuring
    【洛谷T7153】(考试) 中位数
    【洛谷T7152】(考试题目)细胞
    【洛谷1962】 斐波那契数列
    【洛谷1855】 榨取kkksc03
    【HDU2255】奔小康赚大钱
    【洛谷1402】酒店之王
    【洛谷1607】【USACO09FEB】庙会班车
  • 原文地址:https://www.cnblogs.com/shl-blog/p/11184072.html
Copyright © 2011-2022 走看看