hdu 5002 (动态树lct)
Tree
Time Limit: 16000/8000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 920 Accepted Submission(s): 388
Your task is to deal with M operations of 4 types:
1.Delete an edge (x, y) from the tree, and then add a new edge (a, b). We ensure that it still constitutes a tree after adding the new edge.
2.Given two nodes a and b in the tree, change the weights of all the nodes on the path connecting node a and b (including node a and b) to a particular value x.
3.Given two nodes a and b in the tree, increase the weights of all the nodes on the path connecting node a and b (including node a and b) by a particular value d.
4.Given two nodes a and b in the tree, compute the second largest weight on the path connecting node a and b (including node a and b), and the number of times this weight occurs on the path. Note that here we need the strict second largest weight. For instance, the strict second largest weight of {3, 5, 2, 5, 3} is 3.
For each test case, the first line contains two integers N and M (N, M<=10^5). The second line contains N integers, and the i-th integer is the weight of the i-th node in the tree (their absolute values are not larger than 10^4).
In next N-1 lines, there are two integers a and b (1<=a, b<=N), which means there exists an edge connecting node a and b.
The next M lines describe the operations you have to deal with. In each line the first integer is c (1<=c<=4), which indicates the type of operation.
If c = 1, there are four integers x, y, a, b (1<= x, y, a, b <=N) after c.
If c = 2, there are three integers a, b, x (1<= a, b<=N, |x|<=10^4) after c.
If c = 3, there are three integers a, b, d (1<= a, b<=N, |d|<=10^4) after c.
If c = 4 (it is a query operation), there are two integers a, b (1<= a, b<=N) after c.
All these parameters have the same meaning as described in problem description.
For each query operation, output two values: the second largest weight and the number of times it occurs. If the weights of nodes on that path are all the same, just output "ALL SAME" (without quotes).
3 2
1 1 2
1 2
1 3
4 1 2
4 2 3
7 7
5 3 2 1 7 3 6
1 2
1 3
3 4
3 5
4 6
4 7
4 2 6
3 4 5 -1
4 5 7
1 3 4 2 4
4 3 6
2 3 6 5
4 3 6
ALL SAME
1 2
Case #2:
3 2
1 1
3 2
ALL SAME
/*
hdu 5002 (动态树lct) problem:
给你一棵树树,主要包含四个操作:
1 x y u v:断开x,y之间的边 连接上u,v
2 x y w:将x->y之间的点权全部置为w
3 x y w:将x->y之间的点权全部加上w
4 x y:查询x->y之间第二大的 solve:
只是需要维护下第二大值,其它直接套模板 hhh-2016-08-20 17:21:29
*/
#pragma comment(linker,"/STACK:124000000,124000000")
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <vector>
#include <map>
#define lson ch[0]
#define rson ch[1]
#define ll long long
#define clr(a,b) memset(a,b,sizeof(a))
#define key_val ch[ch[root][1]][0]
using namespace std;
const int maxn = 300100;
const int INF = 0x3f3f3f3f; struct Node* null;
struct Node
{
Node* ch[2] ;
Node* fa;
int Size ;
int mMax ;
int sMax ;
int max_num ;
int Max_num ;
int val ;
int add ;
int same ;
int rev;
void newnode(int v)
{
val = v ;
mMax = v ;
sMax = -INF ;
Max_num = 1 ;
max_num = 0 ;
Size = 1 ;
add = 0 ;
same = -INF ;
fa = ch[0] = ch[1] = null ;
rev = 0;
}
void update_rev()
{
if(this == null)
return ;
swap(ch[0],ch[1]);
rev ^= 1;
}
void update_add(int v)
{
if(this == null )return ;
add += v;
mMax += v,val += v;
if(sMax != -INF) sMax += v;
} void update_same(int v)
{
if(this == null) return ;
same = v;
add = 0,val = v,mMax = v;
sMax = -INF,Max_num = Size,max_num = 0;
}
void cal(int val,int num)
{
if ( val == -INF ) return ;
if ( val < sMax ) return ;
if ( val > mMax )
{
sMax = mMax ;
max_num = Max_num ;
mMax = val ;
Max_num = num ;
}
else if ( val == mMax )
{
Max_num += num ;
}
else if ( val > sMax )
{
sMax = val ;
max_num = num ;
}
else max_num += num ;
}
void push_up () {
Size = ch[0]->Size + 1 + ch[1]->Size ;
mMax = sMax = -INF ;
max_num = Max_num = 0 ;
cal ( val , 1 ) ;
cal ( ch[0]->mMax , ch[0]->Max_num ) ;
cal ( ch[0]->sMax , ch[0]->max_num ) ;
cal ( ch[1]->mMax , ch[1]->Max_num ) ;
cal ( ch[1]->sMax , ch[1]->max_num ) ;
} void push_down()
{
if(rev)
{
ch[0]->update_rev();
ch[1]->update_rev();
rev = 0;
}
if(same != -INF)
{
ch[0]->update_same(same);
ch[1]->update_same(same);
same = -INF;
}
if(add)
{
ch[0]->update_add(add);
ch[1]->update_add(add);
add = 0;
}
} void link_child ( Node* to , int d )
{
ch[d] = to;
to->fa = this ;
} int isroot()
{
return fa == null || this != fa->ch[0] && this != fa->ch[1] ;
}
void down()
{
if ( !isroot () ) fa->down () ;
push_down () ;
}
void Rotate ( int d )
{
Node* f = fa ;
Node* ff = fa->fa ;
f->link_child ( ch[d] , !d ) ;
if ( !f->isroot () )
{
if ( ff->ch[0] == f ) ff->link_child ( this , 0 ) ;
else ff->link_child ( this , 1 ) ;
}
else fa = ff ;
link_child (f,d) ;
f->push_up () ;
} void splay ()
{
down () ;
while ( !isroot () ) {
if ( fa->isroot () ) {
this == fa->ch[0] ? Rotate ( 1 ) : Rotate ( 0 ) ;
} else {
if ( fa == fa->fa->ch[0] ) {
this == fa->ch[0] ? fa->Rotate ( 1 ) : Rotate ( 0 ) ;
Rotate ( 1 ) ;
} else {
this == fa->ch[1] ? fa->Rotate ( 0 ) : Rotate ( 1 ) ;
Rotate ( 0 ) ;
}
}
}
push_up () ;
} void access()
{
Node* now = this ;
Node* x = null ;
while ( now != null )
{
now->splay () ;
now->link_child ( x , 1 ) ;
now->push_up () ;
x = now ;
now = now->fa ;
}
splay () ;
} void make_root()
{
access();
update_rev();
} void cut()
{
access();
ch[0]->fa = null;
ch[0] = null;
push_up();
}
Node* find_root ()
{
access () ;
Node* to = this ;
while ( to->ch[0] != null )
{
to->push_down () ;
to = to->ch[0] ;
}
return to ;
}
void cut(Node* to)
{
to->make_root();
cut();
} void link(Node* to)
{
to->make_root();
to->fa = this;
}
void make_same(Node* to,int val)
{
to->make_root();
access();
update_same(val);
}
void make_add(Node* to,int val)
{
to->make_root();
access();
update_add(val);
}
void query(Node* to)
{
to->make_root();
access(); if(!max_num)
printf("ALL SAME\n");
else
printf("%d %d\n",sMax,max_num);
}
};
Node memory_pool[maxn];
Node* now;
Node* node[maxn]; void Clear()
{
now = memory_pool;
now->newnode(-INF);
null = now ++;
null->Size = 0;
} int main()
{
int T,n,cas = 1,m;
int x,y,a,b,c;
int ob;
// freopen("in.txt","r",stdin);
scanf("%d",&T);
while(T--)
{
Clear();
scanf("%d%d",&n,&m);
printf("Case #%d:\n",cas++);
for(int i = 1; i <= n; i++)
{
scanf("%d",&x);
now->newnode(x);
node[i] = now++;
} for(int i = 1; i < n; i++)
{
scanf("%d%d",&a,&b);
node[a]->link(node[b]); }
for(int i= 1; i <= m; i++)
{
scanf("%d",&ob);
if(ob == 1)
{
scanf("%d%d%d%d",&x,&y,&a,&b);
node[x]->cut(node[y]);
node[a]->link(node[b]);
}
else if(ob == 2)
{
scanf("%d%d%d",&x,&y,&c);
node[x]->make_same(node[y],c);
}
else if(ob == 3)
{
scanf("%d%d%d",&x,&y,&c);
node[x]->make_add(node[y],c);
}
else if(ob == 4)
{
scanf("%d%d",&x,&y);
node[x]->query(node[y]); }
}
}
return 0;
}
hdu 5002 (动态树lct)的更多相关文章
- hdu 5398 动态树LCT
GCD Tree Time Limit: 5000/2500 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Su ...
- hdu 5314 动态树
Happy King Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)Tot ...
- HDU 4718 The LCIS on the Tree (动态树LCT)
The LCIS on the Tree Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Oth ...
- 动态树LCT小结
最开始看动态树不知道找了多少资料,总感觉不能完全理解.但其实理解了就是那么一回事...动态树在某种意思上来说跟树链剖分很相似,都是为了解决序列问题,树链剖分由于树的形态是不变的,所以可以通过预处理节点 ...
- bzoj2049-洞穴勘测(动态树lct模板题)
Description 辉辉热衷于洞穴勘测.某天,他按照地图来到了一片被标记为JSZX的洞穴群地区.经过初步勘测,辉辉发现这片区域由n个洞穴(分别编号为1到n)以及若干通道组成,并且每条通道连接了恰好 ...
- [模板] 动态树/LCT
简介 LCT是一种数据结构, 可以维护树的动态加边, 删边, 维护链上信息(满足结合律), 单次操作时间复杂度 \(O(\log n)\).(不会证) 思想类似树链剖分, 因为splay可以换根, 用 ...
- 动态树LCT(Link-cut-tree)总结+模板题+各种题目
一.理解LCT的工作原理 先看一道例题: 让你维护一棵给定的树,需要支持下面两种操作: Change x val: 令x点的点权变为val Query x y: 计算x,y之间的唯一的最短路径的点 ...
- SPOJ OTOCI 动态树 LCT
SPOJ OTOCI 裸的动态树问题. 回顾一下我们对树的认识. 最初,它是一个连通的无向的无环的图,然后我们发现由一个根出发进行BFS 会出现层次分明的树状图形. 然后根据树的递归和层次性质,我们得 ...
- BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊 (动态树LCT)
2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 2843 Solved: 1519[Submi ...
随机推荐
- 关于from nltk.book import * 报错解决方法
import nltk nltk.download() 在使用上面命令安装了nltk库并运行下载后,再输入from nltk.book import * 往往会出现这样的错误提示: 出现这种错误往往是 ...
- 第一部分 linux系统命令
一.linux系统命令 pwd 当前目录位置 / 根目录 cd (change direcory) cd ..返回上一层目录 ls 显示当前目录下文件 ls -l 显示目录下详细文件信息 ls -lh ...
- 400多个开源项目以及43个优秀的Swift开源项目-Swift编程语言资料大合集
Swift 基于C和Objective-C,是供iOS和OS X应用编程的全新语言,更加高效.现代.安全,可以提升应用性能,同时降低开发难度. Swift仍然处于beta测试的阶段,会在iOS 8发布 ...
- JAVA和Android的回调机制
本文出自xiaanming的博客(http://blog.csdn.net/xiaanming/article/details/17483273),请尊重他人的辛勤劳动成果,谢谢 以 前不理解什么叫回 ...
- UTF-8 UTF-16 UTF-32 最根本的区别?
昨天看书的时候突然发现UTF-16 我好像还没见过这个东西 也可能忘记了 反正现在对自己科普一下吧 最根本的区别 UTF-32 把所有的字符都用32bit -- 4个字节 来表示 UTF-16 和 ...
- margin-top导致父标签偏移问题
从一个大神博客中看到这句话: 这个问题发生的原因是根据规范,一个盒子如果没有上补白(padding-top)和上边框(border-top),那么这个盒子的上边距会和其内部文档流中的第一个子元素的上边 ...
- javascript单例模式及开发实践
定义: 保证一个对象(类)仅有一个实例,并提供一个访问它的全局访问点: 实现原理: 利用闭包来保持对一个局部变量的引用,这个变量保存着首次创建的唯一的实例; 主要用于: 全局缓存.登录浮窗等只需要唯一 ...
- C语言学习之弹跳小球
重新回过头来看了一遍C语言,才发现我自己的无知,C语言其实好强大,我之前学的不过是一点C语法和做几个数学题.正好3月份的考试要考C语言,重新学一遍,先是在中国大学mooc上把翁恺老师的C语言刷了一遍, ...
- SpringBoot单元测试中的测试方法执行顺序
一.忽略方法@ignore 二.执行顺序@FixMethodOrder(MethodSorter.JVM) 我们在执行JUnit测试用例时,有时需要按照定义顺序执行单元测试方法,比如如在测试数据库相关 ...
- Spring Security 入门(1-6-2)Spring Security - 内置的filter顺序、自定义filter、http元素和对应的filterChain
Spring Security 的底层是通过一系列的 Filter 来管理的,每个 Filter 都有其自身的功能,而且各个 Filter 在功能上还有关联关系,所以它们的顺序也是非常重要的. 1.S ...