【BZOJ2243】【SDOI2011】染色 (LCT)

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

练了一发LCT,唔调了好久感觉是下传标记的问题可是不知道哪里错了。问了问老司机ljy,确实是出事了。。

唔大概就是 每一次flip的下传要注意一下两个儿子各自的lc和rc吧qwq

  1 #include <cstdio>
  2 #include <cstdlib>
  3 #include <cstring>
  4 #include <iostream>
  5 #define MaxN 200010
  6 using namespace std;
  7 int n, m, top;
  8 int ch[MaxN][2];
  9 int Q[MaxN], sum[MaxN], val[MaxN], type[MaxN], flip[MaxN], p[MaxN], mark[MaxN], lc[MaxN], rc[MaxN];
 10 //splay
 11
 12 bool isroot(int x){
 13     return ch[p[x]][0] != x && ch[p[x]][1] != x;
 14 }
 15
 16 #define l ch[x][0]
 17 #define r ch[x][1]
 18
 19 void push_up(int x){
 20     sum[x] = sum[l] + sum[r] + 1;
 21     if (l) sum[x] -= (rc[l] == val[x]), lc[x] = lc[l]; else lc[x] = val[x];
 22     if (r) sum[x] -= (lc[r] == val[x]), rc[x] = rc[r]; else rc[x] = val[x];
 23 }
 24
 25 void updata(int x, int c){
 26     if (!x) return;
 27     sum[x] = mark[x] = 1;
 28     lc[x] = rc[x] = val[x] = c;
 29 }
 30
 31 void Flip(int x){
 32     flip[x] ^= 1; swap(lc[l], rc[l]); swap(rc[r], lc[r]);
 33 }
 34
 35 #undef l
 36 #undef r
 37
 38 void push_down(int x){
 39     int l = ch[x][0], r = ch[x][1];
 40     if (flip[x]){
 41         flip[x] = 0;
 42         Flip(l); Flip(r);
 43         swap(ch[x][0], ch[x][1]);
 44     }
 45     if (mark[x]){
 46         mark[x] = 0;
 47         updata(l, val[x]); updata(r, val[x]);
 48     }
 49 }
 50
 51 void rotate(int x){
 52     int y = p[x], z = p[y];
 53     if (!isroot(y)) ch[z][ch[z][1] == y] = x;
 54     int l = ch[y][1] == x, r = l ^ 1;
 55
 56     p[x] = z;
 57     p[y] = x;
 58     p[ch[x][r]] = y;
 59
 60     ch[y][l] = ch[x][r];
 61     ch[x][r] = y;
 62     push_up(y); push_up(x);
 63 }
 64
 65 void splay(int x){
 66     int top = 1;
 67     Q[top] = x;
 68     for (int t = x; !isroot(t); t = p[t]) Q[++top] = p[t];
 69     while (top) push_down(Q[top--]);
 70     while (!isroot(x)){
 71         int y = p[x], z = p[y];
 72         if (!isroot(y)){
 73             if ((ch[y][1] == x) ^ (ch[z][1] == y)) rotate(x);
 74             else rotate(y);
 75         }
 76         rotate(x);
 77     }
 78 }
 79
 80 // lct
 81
 82 void Access(int x){
 83     for (int t = 0; x; t = x, x = p[x]) {
 84         splay(x); ch[x][1] = t; push_up(x);
 85     }
 86 }
 87
 88 void Make_root(int x){
 89     Access(x); splay(x); flip[x] ^= 1;
 90 }
 91
 92 void Link(int u, int v){
 93     Make_root(u); p[u] = v;
 94 }
 95
 96 void Split(int u, int v){
 97     Make_root(v); Access(u); splay(u);
 98 }
 99
100 //
101 void Read_Data(){
102     scanf("%d%d", &n, &m);
103     int u, v;
104     //val[0] = rc[0] = lc[0] = -1;
105     for (int i = 1; i <= n; i++) scanf("%d", &val[i]), lc[i] = rc[i] = val[i];
106 //    for (int i = 1; i <= n; i++) sum[i] = 1;
107     for (int i = 1; i < n; i++) {
108         scanf("%d%d", &u, &v);
109         Link(u, v);
110
111 }
112
113 void Solve(){
114     char s[5];
115     int u, v, c;
116     for (int i = 1; i <= m; i++) {
117         scanf("%s%d%d", s, &u, &v);
118         if (s[0] == ‘Q‘) {
119             Split(u, v);
120             printf("%d\n", sum[u]);
121         }
122         else {
123             scanf("%d", &c);
124             Split(u, v); updata(u, c);
125         }
126     }
127 }
128
129 int main(){
130     freopen("paint.in", "r", stdin);
131     freopen("paint.out", "w", stdout);
132     Read_Data();
133     Solve();
134     return 0;
135 }

_(:з」∠)_

时间: 2025-01-09 21:37:41

【BZOJ2243】【SDOI2011】染色 (LCT)的相关文章

bzoj2243 [SDOI2011]染色 动态树

#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define N 110000 int pre[N],ch[N][2]; int e[N],ne[N*2],v[N*2]; int nn,m; int col[N]; int lc[N],sm[N],rc[N],num[N]; int rt[N],n; int qu[N

[BZOJ2243]SDOI2011染色|树链剖分|LCT

裸题嘛.. 先考虑一条线段上如何查询颜色段数,只要对每个线段树节点多维护一个左颜色和右颜色,然后合并的时候sum[x]=sum[lc]+sum[rc]-(左儿子的右颜色==右儿子的左颜色)..实在太久没写树剖结果码+调试花了两节多晚自习,,各种傻逼错误,什么反向边忘加,标记忘记下传...还有就是更新答案的时候,关键的一点是要保证当前的两点(也就是a,b)是没有被更新到的,否则很难搞.. 表示LCT要更好写..不过在BZOJ上我的树链剖分6000+MS,LCT要13000+MS.. 树链剖分: #

BZOJ2243 [SDOI2011]染色

题意:树,路径染色,路径查询分了几段. 分析: 树链剖分套线段树,没写过,代码写得很乱,还犯了不少错,加了点注释,以后不能犯这种错了. #include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define m ((L+R)>>1) #define lc o<<1 #define rc o<<1|1 #define ls lc,L,m

[BZOJ2243][SDOI2011]染色 解题报告|树链剖分

Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段),如“112221”由3段组成:“11”.“222”和“1”. 请你写一个程序依次完成这m个操作. 与上一题差别不大,主要就是solve过程要根据左端点和右端点的颜色处理合并时候的情况 线段树的每个节点要记录颜色段数|最左边的颜色|最右边的颜色 同时往下传的时候标记要做好(之前那道题是单点修改所以不用考虑

BZOJ2243 [SDOI2011]染色(树链剖分+线段树合并)

题目链接 BZOJ2243 树链剖分+线段树合并 线段树合并的一些细节需要注意一下 #include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for (int i(a); i <= (b); ++i) #define dec(i, a, b) for (int i(a); i >= (b); --i) typedef long long LL; const int N = 100010; int n, m,

bzoj2243: [SDOI2011]染色 树链剖分

裸树剖. #include<bits/stdc++.h> using namespace std; #define N 100010 #define M (l+r>>1) #define P (k<<1) #define S (k<<1|1) #define L l,M,P #define R M+1,r,S #define Z int l=1,int r=n,int k=1 typedef int ds[N]; ds dp,num,p,size,son,t

bzoj2243 sdoi2011 染色 paint

明明是裸树剖 竟然调了这么久好蛋疼 大概是自己比较水的原因吧 顺便+fastio来gangbang #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cstdio> #include<cctype> using namespace std; const int Maxn=100010,Maxm=Maxn; int n,

【树链剖分】bzoj2243 [SDOI2011]染色

树链剖分模板题.线段树维护每个段中的颜色数.左端点颜色.右端点颜色. pushup: col[rt]=col[rt<<1]+col[rt<<1|1]-(Rcol[rt<<1]==Lcol[rt<<1|1]); 在合并各个链的答案时,要注意若两头颜色相同,ans--. [教训:树链剖分题在进行建立线段树树时,要注意下面代码中的标注部分.否则会WA] Code: 1 #include<cstdio> 2 #include<algorithm&g

bzoj2243: [SDOI2011]染色--线段树+树链剖分

此题代码量较大..但是打起来很爽 原本不用lca做一直wa不知道为什么.. 后来改lca重打了一遍= =结果一遍就AC了orz 题目比较裸,也挺容易打,主要是因为思路可以比较清晰 另:加读入优化比没加快了1.3s.. 1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 using namespace std; 5 const int maxn = 100010; 6 struct node{

[BZOJ2243][SDOI2011]染色(树链剖分)

[传送门] 树链剖分就行了,注意线段树上颜色的合并 Code #include <cstdio> #include <algorithm> #define N 100010 #define MID int mid=(l+r)>>1,ls=id<<1,rs=id<<1|1 #define len (r-l+1) using namespace std; struct tree{ int lc,rc,sum,tag; tree(){lc=rc=tag