hdu 5002 Tree (LCT)

news/2024/10/22 13:48:18/

hdu 5002 Tree (LCT)

几乎是模板题,维护一个最大值和次大值即可。

代码:

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<stdio.h>
#include<algorithm>
#include<string.h>
#define ls son[0][rt]
#define rs son[1][rt]
using namespace std ;const int maxn = 100001 ;
const int INF = -1110011111 ;
int son[2][maxn] , mx[2][maxn] , cnt[2][maxn] , size[maxn] ;
int  fa[maxn] , is[maxn] , val[maxn] ;
int col[maxn] , add[maxn] , rev[maxn] ;
int st[55] ;
void push_up ( int rt ) {size[rt] = size[ls] + size[rs] + 1 ;st[1] = mx[0][ls] ;st[2] = mx[1][ls] ;st[3] = mx[0][rs] ;st[4] = mx[1][rs] ;st[5] = val[rt] ;sort ( st + 1 , st + 6 ) ;int T = unique ( st + 1 , st + 6 ) - st - 1 ;mx[0][rt] = st[T] , mx[1][rt] = st[T-1] ;cnt[0][rt] = cnt[1][rt] = 0 ;for ( int i = 0 ; i < 2 ; i ++ )for ( int j = 0 ; j < 2 ; j ++ ) {int v = mx[i][son[j][rt]] ;if ( v == mx[0][rt] ) cnt[0][rt] += cnt[i][son[j][rt]] ;if ( v == mx[1][rt] ) cnt[1][rt] += cnt[i][son[j][rt]] ;}if ( val[rt] == mx[0][rt] ) cnt[0][rt] ++ ;if ( val[rt] == mx[1][rt] ) cnt[1][rt] ++ ;
}void reverse ( int rt ) {if ( !rt ) return ;swap ( son[0][rt] , son[1][rt] ) ;rev[rt] ^= 1 ;
}void color ( int rt , int c ) {if ( !rt ) return ;val[rt] = c ;mx[0][rt] = col[rt] = c ;mx[1][rt] = add[rt] = INF ;cnt[0][rt] = size[rt] ;cnt[1][rt] = 0 ;
}void ADD ( int rt , int c ) {if ( !rt ) return ;if ( add[rt] == INF ) add[rt] = c ;else add[rt] += c ;mx[0][rt] += c ;val[rt] += c ;if ( mx[1][rt] != INF ) mx[1][rt] += c ;
}void push_down ( int rt ) {if ( rev[rt] ) {reverse ( ls ) ;reverse ( rs ) ;rev[rt] = 0 ;}if ( col[rt] != INF ) {color ( ls , col[rt] ) ;color ( rs , col[rt] ) ;col[rt] = INF ;}if ( add[rt] != INF ) {ADD ( ls , add[rt] ) ;ADD ( rs , add[rt] ) ;add[rt] = INF ;}
}void down ( int rt ) {if ( !is[rt] ) down ( fa[rt] ) ;push_down ( rt ) ;
}void rot ( int rt ) {int y = fa[rt] , z = fa[y] , c = rt == son[0][y] ;son[!c][y] = son[c][rt] ; fa[son[c][rt]] = y ;son[c][rt] = y ; fa[y] = rt ;fa[rt] = z ;if ( is[y] ) is[y] = 0 , is[rt] = 1 ;else son[y==son[1][z]][z] = rt ;push_up ( y ) ;
}void splay ( int rt ) {down ( rt ) ;while ( !is[rt] ) {int y = fa[rt] , z = fa[y] ;if ( !is[y] ) rot ( (rt==son[0][y]) == (y==son[0][z]) ? y : rt ) ;rot ( rt ) ;}push_up ( rt ) ;
}void access ( int rt ) {for ( int v = 0 ; rt ; rt = fa[rt] ) {splay ( rt ) ;is[rs] = 1 ; is[v] = 0 ;rs = v ;v = rt ;push_up ( rt ) ;}
}void change_root ( int rt ) {access ( rt ) ;splay ( rt ) ;reverse ( rt ) ;
}void cut ( int a , int b ) {change_root ( a ) ;access ( a ) ;splay ( b ) ;fa[b] = 0 ;
}void link ( int a , int b ) {change_root ( b ) ;fa[b] = a ;
}void gao1 ( int a , int b , int c , int d ) {cut ( a , b ) ;link ( c , d ) ;
}void gao2 ( int a , int b , int c ) {change_root ( a ) ;access ( b ) ;splay ( b ) ;color ( b , c ) ;
}void gao3 ( int a , int b , int c ) {change_root ( a ) ;access ( b ) ;splay ( b ) ;ADD ( b , c ) ;
}void print ( int rt ) {if ( !rt ) return ;printf ( "rt = %d , mx0 = %d , mx1 = %d\n" , rt , mx[0][rt] , mx[1][rt] ) ;print ( ls ) ;print ( rs ) ;
}
void gao4 ( int a , int b ) {change_root ( a ) ;access ( b ) ;splay ( b ) ;//   print ( b ) ;if ( mx[1][b] == INF ) puts ( "ALL SAME" ) ;else printf ( "%d %d\n" , mx[1][b] , cnt[1][b] ) ;
}void init ( int rt ) {int a ;scanf ( "%d" , &a ) ;val[rt] = mx[0][rt] = a ;mx[1][rt] = INF ;cnt[0][rt] = 1 ;cnt[1][rt] = 0 ;size[rt] = 1 ;add[rt] = col[rt] = INF ;son[0][rt] = son[1][rt] = fa[rt] = rev[rt] = 0 ;is[rt] = 1 ;
}int main () {int T , ca = 0 ;int n , m ;
//    freopen ( "main.in" , "r" , stdin ) ;mx[0][0] = mx[1][0] = INF ;is[0] = 1 , fa[0] = 0 ;scanf ( "%d" , &T ) ;while ( T -- ) {scanf ( "%d%d" , &n , &m ) ;for ( int i = 1 ; i <= n ; i ++ )init ( i ) ;for ( int i = 1 ; i < n ; i ++ ) {int a , b ;scanf ( "%d%d" , &a , &b ) ;link ( a , b ) ;}printf ( "Case #%d:\n" , ++ ca ) ;for ( int i = 1 ; i <= m ; i ++ ) {int a , b , c , d ;scanf ( "%d" , &c ) ;if ( c == 1 ) {int f ;scanf ( "%d%d%d%d" , &a , &b , &d , &f ) ;if ( a == b || d == f ) continue ;gao1 ( a , b , d , f ) ;} else if ( c == 2 ) {scanf ( "%d%d%d" , &a , &b , &d ) ;gao2 ( a , b , d ) ;} else if ( c == 3 ) {scanf ( "%d%d%d" , &a , &b , &d ) ;gao3 ( a , b , d ) ;} else {scanf ( "%d%d" , &a , &b ) ;gao4 ( a , b ) ;}}}
}
/*
2
3 2
1 1 2
1 2
1 3
4 2 3
*/



http://www.ppmy.cn/news/712768.html

相关文章

洛谷P5002 专心OI - 找祖先 树上统计+LCA+次方余项

洛谷P5002 专心OI - 找祖先 标签 LCA树上统计次方余项的计算 简明题意 给一颗有根树&#xff0c;再给m个询问&#xff0c;对于某个节点x&#xff0c;有多少对节点的LCA是x 思路 这题非常简单。我们假设要求x的答案。显然&#xff0c;LCA是x的一对节点&#xff0c; u&#xf…

HDU 5002 Tree

题意&#xff1a; 一棵树 支持删边加边、路径权值加值、路径权值改值、路径求第二大的数字和其个数 思路&#xff1a; LCT的第二题 题意已经把功能都告诉了 比较裸 要注意的是权值加值和改值两个操作的标记下放问题 要先down改值 再down加值 对于路径的操作通过mroot…

例5002 进制转换

例5002 进制转换 Time Limit: 1000/1000MS (C/Others) Memory Limit: 65536/65536KB (C/Others) Total Submissions: 190 Accepted Submissions: 39 Problem Description 输入一个十进制数N&#xff0c;将它转换成R进制数输出。 Input 输入数据包含多个测试实例&#xff0c;每…

LCT - hdu5002 Tree

题目&#xff1a; http://acm.hdu.edu.cn/showproblem.php?pid5002 题意&#xff1a; 给一棵树树&#xff0c;提供四种操作 1&#xff1a;删除(x,y)边&#xff0c;添加(a,b)边&#xff0c;保证操作前后都是合法的树 2&#xff1a;修改a--b路径上所有点的权值为x 3&#…

1144: 5002 进制转换

题目描述 输入一个十进制数N&#xff0c;将它转换成R进制数输出。 输入 输入数据包含多个测试实例&#xff0c;每个测试实例包含两个整数N&#xff08;32位整数&#xff09;和R&#xff08;2<R<16&#xff0c;R ! 10&#xff09;。 输出 为每个测试实例输出转换后的…

hdu5002:Tree (LCT)

题目传送门&#xff1a;http://acm.hdu.edu.cn/showproblem.php?pid5002 题目大意&#xff1a;一开始给你一棵有N个点的树&#xff08;N<10^5&#xff09;&#xff0c;每个点有权值。现在有四种操作&#xff1a;1&#xff1a;x y a b删掉连接x,y的边&#xff0c;并连接a,b…

P5002 专心OI - 找祖先【题解】

题目链接&#xff1a;P5002 专心OI - 找祖先。 这是一道既和 LCA 有关&#xff0c;又可以称得上和 LCA 没有多少关系的题。 这道题中的数据范围告诉我们&#xff0c;存图要用邻接表&#xff08;矩阵表示很悲伤&#xff09;&#xff0c;所以先把它的代码给码上&#xff1a; /…

InetAddress.getLocalHost().getHostName() took 5002 milliseconds to respond.

1.使用工具 MAC idea mysql 2.错误场景 在启动项目的时候报错&#xff1a; InetAddress.getLocalHost().getHostName() took 5002 milliseconds to respond.3.解决方案 获取本机的主机名称&#xff08;mac电脑&#xff09; 可以使用 hostname命令 hostname 就可以拿到 **…