BZOJ2243: [SDOI2011]染色

2243: [SDOI2011]染色

Time Limit: 20 Sec  Memory Limit: 512 MB
Submit: 9235  Solved: 3469
[Submit][Status][Discuss]

Description

给定一棵有n个节点的无根树和m个操作,操作有2类:
1、将节点a到节点b路径上所有点都染成颜色c;
2、询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段),
如“112221”由3段组成:“11”、“222”和“1”。
请你写一个程序依次完成这m个操作。

Input

第一行包含2个整数n和m,分别表示节点数和操作数;
第二行包含n个正整数表示n个节点的初始颜色
下面 行每行包含两个整数x和y,表示x和y之间有一条无向边。
下面 行每行描述一个操作:
“C a b c”表示这是一个染色操作,把节点a到节点b路径上所有点(包括a和b)都染成颜色c;
“Q a b”表示这是一个询问操作,询问节点a到节点b(包括a和b)路径上的颜色段数量。

Output

对于每个询问操作,输出一行答案。

Sample Input

6 5
2 2 1 2 1 1
1 2
1 3
2 4
2 5
2 6
Q 3 5
C 2 1 1
Q 3 5
C 5 1 2
Q 3 5

Sample Output

3
1
2

HINT

数N<=10^5,操作数M<=10^5,所有的颜色C为整数且在[0, 10^9]之间。

Source

第一轮day1

 

【题解】

树剖+sgt,维护色块数,左边颜色,右边颜色,注意颜色可以为0

询问的时候,用t1,t2分别维护左右两条链的sgt节点合并,以及单链情况的时候,看看是u跳还是v跳(比较深度),决定应该与t1合并还是与t2合并

t1 t2方向相反,交换其中一个的lc,rc,合并t1,t2即为询问答案

修改略

还因为build的时候,把tid当rank了。。。全WA。。

 

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <cstdlib>
  5 #include <algorithm>
  6 #include <queue>
  7 #include <vector>
  8 #include <map>
  9 #include <string> 
 10 #include <cmath> 
 11 #define min(a, b) ((a) < (b) ? (a) : (b))
 12 #define max(a, b) ((a) > (b) ? (a) : (b))
 13 #define abs(a) ((a) < 0 ? (-1 * (a)) : (a))
 14 template<class T>
 15 inline void swap(T &a, T &b)
 16 {
 17     T tmp = a;a = b;b = tmp;
 18 }
 19 inline void read(int &x)
 20 {
 21     x = 0;char ch = getchar(), c = ch;
 22     while(ch < '0' || ch > '9') c = ch, ch = getchar();
 23     while(ch <= '9' && ch >= '0') x = x * 10 + ch - '0', ch = getchar();
 24     if(c == '-') x = -x;
 25 }
 26 const int INF = 0x3f3f3f3f;
 27 const int MAXN = 1000000 + 10;
 28 int n,m,start[MAXN],rank[MAXN],tim,size[MAXN],top[MAXN],son[MAXN],deep[MAXN],fa[MAXN],tid[MAXN], head[MAXN], cnt;
 29 struct Edge
 30 {
 31     int u,v,nxt;
 32     Edge(int _u, int _v, int _nxt){u = _u;v = _v;nxt = _nxt;}
 33     Edge(){}
 34 }edge[MAXN << 1];
 35 inline void insert(int a, int b)
 36 {
 37     edge[++cnt] = Edge(a,b,head[a]);
 38     head[a] = cnt;
 39 }
 40 struct Node
 41 {
 42     int l,r,sum,lc,rc,lazy;
 43     Node(){l = r = lazy = lc = rc = -1;sum = 0;}
 44 }node[MAXN << 2];
 45 Node merge(Node &a, Node &b)
 46 {
 47     if(a.l == -1) return b;
 48     else if(b.l == -1) return a;
 49     Node re;
 50     re.l = a.l, re.r = b.r, re.sum = a.sum + b.sum;
 51     if(a.rc == b.lc && a.rc != -1) -- re.sum;
 52     re.lc = a.lc, re.rc = b.rc;
 53     return re;
 54 }
 55 void pushup(int o)
 56 {
 57     if(node[o].lazy == -1) return;
 58     node[o << 1].lazy = node[o << 1 | 1].lazy = node[o].lazy;
 59     node[o << 1].sum = node[o << 1 | 1].sum = 1;
 60     node[o << 1].lc = node[o << 1].rc = node[o << 1 | 1].lc = node[o << 1 | 1].rc = node[o].lazy;
 61     node[o].lazy = -1;
 62 }
 63 void build(int o = 1, int l = 1, int r = n)
 64 {
 65     if(l == r)
 66     {
 67         node[o].l = l,node[o].r = r,node[o].sum = 1,node[o].lc = node[o].rc = start[rank[l]];
 68         return;
 69     }
 70     int mid = (l + r) >> 1;
 71     build(o << 1, l, mid);
 72     build(o << 1 | 1, mid + 1, r);
 73     node[o] = merge(node[o << 1], node[o << 1 | 1]);
 74 }
 75 void modify(int ll, int rr, int k, int o = 1)
 76 {
 77     pushup(o);
 78     if(ll <= node[o].l && rr >= node[o].r)
 79     {
 80         node[o].lc = node[o].rc = node[o].lazy = k;
 81         node[o].sum = 1;
 82         return;
 83     }
 84     int mid = (node[o].l + node[o].r) >> 1;
 85     if(mid >= ll) modify(ll, rr, k, o << 1);
 86     if(mid < rr) modify(ll, rr, k, o << 1 | 1);
 87     node[o] = merge(node[o << 1], node[o << 1 | 1]);
 88 }
 89 Node ask(int ll, int rr, int o = 1)
 90 {
 91     pushup(o);
 92     if(ll <= node[o].l && rr >= node[o].r) return node[o];
 93     Node a, b;
 94     int mid = (node[o].l + node[o].r) >> 1;
 95     if(mid >= ll) a = ask(ll, rr, o << 1);
 96     if(mid < rr) b = ask(ll, rr, o << 1 | 1);
 97     return merge(a, b);
 98 }
 99 void dfs1(int x)
100 {
101     size[x] = 1;
102     for(int pos = head[x];pos;pos = edge[pos].nxt)
103     {
104         int v = edge[pos].v;
105         if(v == fa[x]) continue;
106         deep[v] = deep[x] + 1, fa[v] = x, dfs1(v), size[x] += size[v];
107         if(son[x] == -1 || size[v] > size[son[x]]) son[x] = v;
108     }
109 }
110 void dfs2(int u, int tp)
111 {
112     top[u] = tp, tid[u] = ++ tim, rank[tim] = u;
113     if(son[u] == -1) return;
114     dfs2(son[u], tp);
115     for(int pos = head[u];pos;pos = edge[pos].nxt)
116     {
117         int v = edge[pos].v;
118         if(v != son[u] & v != fa[u]) dfs2(v, v);
119     }
120 }
121 int query(int u, int v)
122 {
123     int f1 = top[u], f2 = top[v], tag = 1;
124     Node t1, t2, tmp;
125     while(f1 != f2)
126     {
127         if(deep[f1] < deep[f2]) swap(f1, f2), swap(u, v), swap(t1, t2);
128         tmp = ask(tid[f1], tid[u]);
129         t1 = merge(tmp, t1);
130         u = fa[f1];f1 = top[u];
131     }    
132     if(deep[u] > deep[v]) swap(u, v);
133     else if(deep[u] < deep[v]) swap(t1, t2);
134     tmp = ask(tid[u], tid[v]);
135     t1= merge(tmp, t1);swap(t1.lc, t1.rc);
136     tmp = merge(t1, t2);
137     return tmp.sum;
138 }
139 void change(int u, int v, int c)
140 {
141     int f1 = top[u], f2 = top[v];
142     while(f1 != f2)
143     {
144         if(deep[f1] < deep[f2]) swap(f1, f2), swap(u, v);
145         modify(tid[f1], tid[u], c);
146         u = fa[f1], f1 = top[u]; 
147     }
148     if(deep[u] > deep[v]) swap(u, v);
149     modify(tid[u], tid[v], c);
150 }
151 int tmp1,tmp2,tmp3;
152 char c;
153 int main()
154 {
155     read(n), read(m);
156     for(int i = 1;i <= n;++ i) read(start[i]);
157     for(int i = 1;i < n;++ i) read(tmp1), read(tmp2), insert(tmp1, tmp2), insert(tmp2, tmp1);
158     memset(son, -1, sizeof(son)), dfs1(1), dfs2(1,1), build();
159     for(int i = 1;i <= m;++ i)
160     {
161         scanf("%s", &c);
162         if(c == 'Q') read(tmp1), read(tmp2), printf("%d\n", query(tmp1, tmp2)); 
163         else read(tmp1), read(tmp2), read(tmp3), change(tmp1, tmp2, tmp3);
164     }
165     return 0;
166 }

 

 

 

 

posted @ 2018-01-30 08:16  嘒彼小星  阅读(151)  评论(0编辑  收藏  举报