【BZOJ2814】tree
2016-02-15 11:16
393 查看
Description
给出一棵N 个点的树,每个点有两层,每层有权值和颜色(黑白) 。要求支持以下操作。
1. Cover s t color 将s到t的路径上的点的两层的颜色全部置为 color(0 白1 黑)
2. CVal index layer val 将index号点的 layer 层的权值修改为 val
3. CColor index layer color 将 index号点的 layer 层的颜色修改为 color
4. QMax s t 询问s到 t的路径上的白色最大权值和路径的权值(任意白色层为起点,每次只能往相同点不同层或者相邻点同一层上移动,每个点的每一层最多走一次,路径经过的层必须都是白色) ,若 s到 t上的路径没有白点则输出[Bad Request.]
5. QLen s t 询问s到t的路径上的白色最大权值和路径的长度,若 s到 t的路径上没有白点则输出 0
初始树上权值均为 1,颜色均为白色。
N<=5W,Q<=5W,1<=val<=1K,0<=color,layer<=1 所有数据不超过longint范围。 .
对于40%的分数,没有 1,5 号操作,N,Q <= 1K
对于80%的分数,没有 5号操作
Input
第一行一个数 N,接下来N*2-2 个数 s,t,代表 s与t之间有连边。第N+1行一个数 Q,
表示操作数。接下来Q 行每行一个操作。
Output
对于每次 QMax,QLen输出对应答案,用换行符分隔。
Sample Input
6
1 2 2 4 2 5 1 3 3 6
7
CVal 1 0 5
CVal 1 1 3
CColor 1 0 1
CVal 2 0 5
CVal 3 0 3
QMax 5 6
QLen 5 6
Sample Output
17
9
HINT
Source
人生成就,写过最长的码农题
半天写代码,半天调代码
LCT大法好啊,比链剖看着美观多了QwQ
给出一棵N 个点的树,每个点有两层,每层有权值和颜色(黑白) 。要求支持以下操作。
1. Cover s t color 将s到t的路径上的点的两层的颜色全部置为 color(0 白1 黑)
2. CVal index layer val 将index号点的 layer 层的权值修改为 val
3. CColor index layer color 将 index号点的 layer 层的颜色修改为 color
4. QMax s t 询问s到 t的路径上的白色最大权值和路径的权值(任意白色层为起点,每次只能往相同点不同层或者相邻点同一层上移动,每个点的每一层最多走一次,路径经过的层必须都是白色) ,若 s到 t上的路径没有白点则输出[Bad Request.]
5. QLen s t 询问s到t的路径上的白色最大权值和路径的长度,若 s到 t的路径上没有白点则输出 0
初始树上权值均为 1,颜色均为白色。
N<=5W,Q<=5W,1<=val<=1K,0<=color,layer<=1 所有数据不超过longint范围。 .
对于40%的分数,没有 1,5 号操作,N,Q <= 1K
对于80%的分数,没有 5号操作
Input
第一行一个数 N,接下来N*2-2 个数 s,t,代表 s与t之间有连边。第N+1行一个数 Q,
表示操作数。接下来Q 行每行一个操作。
Output
对于每次 QMax,QLen输出对应答案,用换行符分隔。
Sample Input
6
1 2 2 4 2 5 1 3 3 6
7
CVal 1 0 5
CVal 1 1 3
CColor 1 0 1
CVal 2 0 5
CVal 3 0 3
QMax 5 6
QLen 5 6
Sample Output
17
9
HINT
Source
人生成就,写过最长的码农题
半天写代码,半天调代码
LCT大法好啊,比链剖看着美观多了QwQ
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #define MAXN 50010 #define GET (ch >= '0' && ch <= '9') #define MAXINT 0x3f3f3f3f using namespace std; int n,m; int sta[MAXN],top; char ch[8]; inline void in(int &x) { char ch = getchar() ; x = 0; while (!GET) ch = getchar(); while (GET) x = x * 10 + ch - '0' , ch = getchar(); } //节点颜色 1为白色 0为黑色 //Data Transmit inline void update(int &a,int &b,int c,int d) { if (a < c) a = c , b = d; else if (a == c && b < d) b = d; } //Define Information Node struct treenode { int len1[2][2],len2[2][2]; int val1[2][2],val2[2][2]; int llen[2],rlen[2]; int lval[2],rval[2]; int minn[2][2]; int size,sum; int maxl,maxv; treenode() { for (int i = 0 ; i <= 1 ; i++) lval[i] = rval[i] = llen[i] = rlen[i] = -MAXINT; maxl = maxv = -MAXINT , size = sum = 0; for (int i = 0 ; i <= 1 ; i++) for (int j = 0 ; j <= 1 ; j++) len1[i][j] = len2[i][j] = val1[i][j] = val2[i][j] = -MAXINT, minn[i][j] = MAXINT; } //Node Union inline friend treenode operator + (const treenode& a,const treenode& b) { treenode ret; for (int i = 0 ; i <= 1 ; i++) for (int j = 0 ; j <= 1 ; j++) //floyed { for (int k = 0 ; k <= 1 ; k++) update(ret.val1[i][j] , ret.len1[i][j] , a.val1[i][k] + b.val1[k][j] , a.len1[i][k] + b.len1[k][j]), update(ret.val2[i][j] , ret.len2[i][j] , a.val2[i][k] + b.val2[k][j] , a.len2[i][k]+b.len2[k][j]), update(ret.lval[i] , ret.llen[i] , a.val1[i][k] + b.lval[k] , a.len1[i][k] + b.llen[k]), update(ret.rval[j] , ret.rlen[j] , a.rval[k] + b.val2[j][k] , a.rlen[k] + b.len2[k][j]), ret.minn[i][j] = min(ret.minn[i][j] , min(a.minn[i][k] , b.minn[k][j])); update(ret.lval[i] , ret.llen[i] , a.lval[i] , a.llen[i]); update(ret.rval[j] , ret.rlen[j] , b.rval[j] , b.rlen[j]); } update(ret.maxv , ret.maxl , a.maxv , a.maxl); update(ret.maxv , ret.maxl , b.maxv , b.maxl); for (int i = 0 ; i <= 1 ; i++) update(ret.maxv , ret.maxl , a.rval[i] + b.lval[i] , a.rlen[i] + b.llen[i]); ret.size = a.size + b.size ; ret.sum = a.sum + b.sum; return ret; } }; //Define LCT struct splay { int ch[2],fa,val[2]; bool flag,cov,col[2]; treenode w; }tree[MAXN]; //Get Node inline treenode findnode(int x) { treenode ret ; ret.size = 2 ; ret.sum = tree[x].val[0] + tree[x].val[1]; for (int i = 0 ; i <= 1 ; i++) for (int j = 0 ; j <= 1 ; j++) { ret.minn[i][j] = min(tree[x].val[i] , tree[x].val[j]); if (tree[x].col[i] && tree[x].col[j]) { ret.len1[i][j] = ret.len2[i][j] = (i == j ? 1 : 2), ret.val1[i][j] = ret.val2[i][j] = (i == j ? tree[x].val[i] : tree[x].val[i] + tree[x].val[j]); update(ret.maxv , ret.maxl , ret.val1[i][j] , ret.len1[i][j]), update(ret.lval[i] , ret.llen[i] , ret.val1[i][j] , ret.len1[i][j]), update(ret.rval[j] , ret.rlen[j] , ret.val2[i][j] , ret.len2[i][j]); } } return ret; } //Information Update inline void push_up(int x) { if (!x) return; tree[x].w = findnode(x); if (tree[x].ch[0]) tree[x].w = tree[tree[x].ch[0]].w + tree[x].w; if (tree[x].ch[1]) tree[x].w = tree[x].w + tree[tree[x].ch[1]].w; } inline void Cover(int x,bool col) { treenode ret; tree[x].flag = 1 , tree[x].cov = col; tree[x].col[0] = tree[x].col[1] = col; if (col) { if ((tree[x].w.size >> 1) & 1) { for (int i = 0 ; i <= 1 ; i++) for (int j = 0 ; j <= 1 ; j++) if (i != j) ret.len1[i][j] = ret.len2[i][j] = tree[x].w.size, ret.val1[i][j] = ret.val2[i][j] = tree[x].w.sum; else ret.len1[i][j] = ret.len2[i][j] = tree[x].w.size - 1, ret.val1[i][j] = ret.val2[i][j] = tree[x].w.sum - tree[x].w.minn[i][j]; } else { for (int i = 0 ; i <= 1 ; i++) for (int j = 0 ; j <= 1 ; j++) if (i == j) ret.len1[i][j] = ret.len2[i][j] = tree[x].w.size, ret.val1[i][j] = ret.val2[i][j] = tree[x].w.sum; else ret.len1[i][j] = ret.len2[i][j] = tree[x].w.size - 1, ret.val1[i][j] = ret.val2[i][j] = tree[x].w.sum - tree[x].w.minn[i][j]; } ret.maxl = tree[x].w.size ; ret.maxv = tree[x].w.sum; for (int i = 0 ; i <= 1 ;i++) ret.llen[i] = ret.rlen[i] = tree[x].w.size, ret.lval[i] = ret.rval[i] = tree[x].w.sum; } ret.size = tree[x].w.size ; ret.sum = tree[x].w.sum; for (int i = 0 ; i <= 1 ; i++) for (int j = 0 ; j <= 1 ; j++) ret.minn[i][j] = tree[x].w.minn[i][j]; tree[x].w = ret; } inline void push_down(int x) { if (!x) return; if (tree[x].flag) { if (tree[x].ch[0]) Cover(tree[x].ch[0] , tree[x].cov); if (tree[x].ch[1]) Cover(tree[x].ch[1] , tree[x].cov); tree[x].flag = 0 ; tree[x].cov = 0; } } //LCT Operation inline bool is_root(int x) { return tree[tree[x].fa].ch[0] != x && tree[tree[x].fa].ch[1] != x; } inline void rot(int x) { int y = tree[x].fa,z = tree[y].fa,l,r; l = (tree[y].ch[1] == x) ; r = l ^ 1; if (!is_root(y)) tree[z].ch[tree[z].ch[1] == y] = x; tree[x].fa = z;tree[y].fa = x ; tree[tree[x].ch[r]].fa = y; tree[y].ch[l] = tree[x].ch[r] ; tree[x].ch[r] = y; push_up(y) ; push_up(x); } inline void Splay(int x) { sta[++top] = x; for (int i = x ; !is_root(i) ; i = tree[i].fa) sta[++top] = tree[i].fa; while (top) push_down(sta[top--]); while (!is_root(x)) { int y = tree[x].fa , z = tree[y].fa; if (!is_root(y)) { if ((tree[z].ch[0] == y) ^ (tree[y].ch[0] == x)) rot(x); else rot(y); } rot(x); } } inline void access(int x) { for (int i = 0 ; x ; i = x , x = tree[x].fa) Splay(x) , tree[x].ch[1] = i , push_up(x); } //Paint Color (Operation No.1) inline void Set_color(int s,int t,bool col) { access(s); for (int x = t , i = 0 ; x ; i = x , x = tree[x].fa) { Splay(x); if (!tree[x].fa) { tree[x].col[0] = tree[x].col[1] = col; if (tree[x].ch[1]) Cover(tree[x].ch[1] , col); if (i) Cover(i , col); } tree[x].ch[1] = i ; push_up(x); } } //Node Modify (Operation No.2/3) inline void modify_val(int x,int y,int z) { Splay(x) ; tree[x].val[y] = z ; push_up(x); } inline void modify_col(int x,int y,bool z) { Splay(x) ; tree[x].col[y] = z ; push_up(x); } //Query (Operation 4/5) inline treenode query(int s,int t) { access(s); for (int x = t , i = 0 ; x ; i = x , x = tree[x].fa) { Splay(x); if (!tree[x].fa) { treenode ret = findnode(x); if (tree[x].ch[1]) { treenode tmp = tree[tree[x].ch[1]].w; for (int i = 0 ; i <= 1 ; i++) for (int j = 0 ; j <= 1 ; j++) swap(tmp.len1[i][j] , tmp.len2[i][j]), swap(tmp.val1[i][j] , tmp.val2[i][j]); for (int i = 0 ; i <= 1 ; i++) swap(tmp.llen[i] , tmp.rlen[i]) , swap(tmp.lval[i] , tmp.rval[i]); ret = tmp + ret; } if (i) ret = ret + tree[i].w; return ret; } tree[x].ch[1] = i ; push_up(x); } } //initialization inline void init() { for (int i = 1 ; i <= n ; i++) { for (int j = 0 ; j <= 1 ; j++) tree[i].val[j] = tree[i].col[j] = 1; tree[i].w = findnode(i); } } //DFS build Tree int Top; struct edge { int to; edge *next; }e[MAXN<<1],*prev[MAXN]; void insert(int u,int v) { e[++Top].to = v ; e[Top].next = prev[u] ; prev[u] = &e[Top]; } void dfs(int x,int f) { tree[x].fa = f; for (edge *i = prev[x] ; i ; i = i->next) if (i->to != f) { if (!tree[x].ch[1]) tree[x].ch[1] = i->to; dfs(i->to , x); } } //debug void printnode(treenode x) { for (int i = 0 ; i <= 1 ; i++) for (int j = 0 ; j <= 1 ; j++) printf("%d ",x.val1[i][j]); for (int i = 0 ; i <= 1 ; i++) for (int j = 0 ; j <= 1 ; j++) printf("%d ",x.val2[i][j]); printf("\n"); for (int i = 0 ; i <= 1 ; i++) for (int j = 0 ; j <= 1 ; j++) printf("%d ",x.len1[i][j]); for (int i = 0 ; i <= 1 ; i++) for (int j = 0 ; j <= 1 ; j++) printf("%d ",x.len2[i][j]); printf("\n"); for (int i = 0 ; i <= 1 ; i++) printf("%d ",x.llen[i]); for (int i = 0 ; i <= 1 ; i++) printf("%d ",x.rlen[i]); printf("\n"); for (int i = 0 ; i <= 1 ; i++) printf("%d ",x.lval[i]); for (int i = 0 ; i <= 1 ; i++) printf("%d ",x.rval[i]); printf("\n"); for (int i = 0 ; i <= 1 ; i++) for (int j = 0 ; j <= 1 ; j++) printf("%d ",x.minn[i][j]); printf("\n"); printf("%d %d %d %d\n",x.size , x.sum , x.maxl , x.maxv); } void print(int x) { printf("%d\n" , x); printf("%d %d %d %d %d %d %d %d %d\n" , tree[x].ch[0] , tree[x].ch[1] , tree[x].fa , tree[x].val[0] , tree[x].val[1] , tree[x].flag , tree[x].cov , tree[x].col[0] , tree[x].col[1]); printnode(tree[x].w); } int main() { in(n) ; int u,v,w ; init() ; for (int i = 1 ; i < n ; i++) in(u) , in(v) , insert(u , v) , insert(v , u); dfs(1 , 0); for (int i = 1 ; i <= n ; i++) if (!tree[i].ch[1]) Splay(i); for (in(m) ; m ; m--) { scanf("%s",ch); if (ch[1] == 'o') in(u) , in(v) , in(w) , Set_color(u , v , w ^ 1); if (ch[1] == 'V') in(u) , in(v) , in(w) , modify_val(u , v , w); if (ch[1] == 'C') in(u) , in(v) , in(w) , modify_col(u , v , w ^ 1); if (ch[1] == 'M') { in(u) , in(v) ; treenode ans = query(u , v); if (ans.maxv < 0) puts("Bad Request."); else printf("%d\n" , ans.maxv); } if (ch[1] == 'L') { in(u) , in(v) ; treenode ans = query(u , v); printf("%d\n" , max(ans.maxl , 0)); } } }
相关文章推荐
- [BZOJ2594][WC2006][LCT][MST]水管局长数据加强版
- 【LCT】BZOJ2049[Sdoi2008]Cave 洞穴勘测
- SPOJ QTREE LCT
- BZOJ1180 [CROATIAN2009]OTOCI
- bzoj2049: [Sdoi2008]Cave 洞穴勘测
- bzoj-2001 City 城市建设
- bzoj-2555 SubString
- bzoj-1180 OTOCI
- Aizu 2450 Do use segment tree LCT
- 【NOI2014】【BZOJ3669】魔法森林
- 【WC2006】【BZOJ2594】水管局长数据加强版
- 【BZOJ4025】二分图
- 【SDOI2014】【BZOJ3531】旅行
- 【WC2005】【BZOJ1453】Dface双面棋盘
- 【BZOJ3282】Tree
- 论在LCT上下放标记
- BZOJ 2001 Hnoi2010 城市建设 分治+LCT
- LCT(Link Cut Tree)学习小记
- BZOJ 4202: 石子游戏 SG定理+LCT
- [BZOJ2959]长跑(LCT)