[Stained] SDOI2011

Description

Given a tree and a number of operations, each tree can select the path between any two points dyed in one color, or the number of color segments on the path between any two queries.

Solution

Tree chain split is not explained, the main analysis segment tree maintenance, tree section on the line segment we maintain the color range of the left and right ends of the color, the number of colors the entire range segment. So when we merged two sections, we first segment the number of colors by adding two sections, the left section if the right colors color intervals equal to the right of the left, then the answer is minus one.

The remaining operation is the basic chain segment tree and the tree is split, are not repeated here.

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         years + 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 << endl << years; 
142      }
 143      if (dep [x]> dep [y]) swap (x, y);
144      years + query = ( 1 , 1 , tot, seg [x], seg [y]);
145      // cout << endl << years; 
146      return years;
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\n", find(x, y));
172         }
173     }
174     return 0;
175 }
AC Code

 

Guess you like

Origin www.cnblogs.com/shl-blog/p/11184072.html