Tree

Time Limit: 16000/8000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 920    Accepted Submission(s): 388

Problem Description
You are given a tree with N nodes which are numbered by integers 1..N. Each node is associated with an integer as the weight.

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.

 
Input
The first line contains an integer T (T<=3), which means there are T test cases in the input.

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.

 
Output
For each test case, first output "Case #x:"" (x means case ID) in a separate line.

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).

 
Sample Input
2
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
 
Sample Output
Case #1:
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)的更多相关文章

  1. hdu 5398 动态树LCT

    GCD Tree Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Su ...

  2. hdu 5314 动态树

    Happy King Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Tot ...

  3. 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 ...

  4. 动态树LCT小结

    最开始看动态树不知道找了多少资料,总感觉不能完全理解.但其实理解了就是那么一回事...动态树在某种意思上来说跟树链剖分很相似,都是为了解决序列问题,树链剖分由于树的形态是不变的,所以可以通过预处理节点 ...

  5. bzoj2049-洞穴勘测(动态树lct模板题)

    Description 辉辉热衷于洞穴勘测.某天,他按照地图来到了一片被标记为JSZX的洞穴群地区.经过初步勘测,辉辉发现这片区域由n个洞穴(分别编号为1到n)以及若干通道组成,并且每条通道连接了恰好 ...

  6. [模板] 动态树/LCT

    简介 LCT是一种数据结构, 可以维护树的动态加边, 删边, 维护链上信息(满足结合律), 单次操作时间复杂度 \(O(\log n)\).(不会证) 思想类似树链剖分, 因为splay可以换根, 用 ...

  7. 动态树LCT(Link-cut-tree)总结+模板题+各种题目

    一.理解LCT的工作原理 先看一道例题: 让你维护一棵给定的树,需要支持下面两种操作: Change x val:  令x点的点权变为val Query x y:  计算x,y之间的唯一的最短路径的点 ...

  8. SPOJ OTOCI 动态树 LCT

    SPOJ OTOCI 裸的动态树问题. 回顾一下我们对树的认识. 最初,它是一个连通的无向的无环的图,然后我们发现由一个根出发进行BFS 会出现层次分明的树状图形. 然后根据树的递归和层次性质,我们得 ...

  9. BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊 (动态树LCT)

    2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 2843  Solved: 1519[Submi ...

随机推荐

  1. 冲刺NO.5

    Alpha冲刺第五天 站立式会议 项目进展 今日项目完成内容主要包括了JS的学习,事务管理员模块与学生模块的完善与补充,并且开始编写信用信息管理模块和奖惩事务管理模块. 问题困难 前端部分的技术掌握的 ...

  2. python3变量和数据类型

        变量和数据类型 知识点 python 关键字 变量的定义与赋值 input() 函数 字符串的格式化 实验步骤 每一种编程语言都有它们自己的语法规则,就像我们所说的外语. 1. 关键字和标识符 ...

  3. 点击tableViewCell,调用打电话的功能

    对于点击tableViewCell,调用打电话的功能,按照一般的方法,使用Appdelegate的OpenUrl的方法,使用前先使用UIAlertView展示,让用户选择是否拨打,但是发现了个简单的方 ...

  4. IntelliJ IDEA插件——冷门神器分享

    IntelliJ IDEA就不必介绍了,至今还能保持IDE前三的神器,如今java程序员的首选,今天介绍几款冷门但绝对是神器的IDEA插件. 前言 IDEA自不必说,IDEA插件是开发中必备的神器,相 ...

  5. 我的PCB电路设计(一)

    我的制板规则 过孔大小:14/24mil-(12/22-28/50)  一般过孔没必要太大.如果电流较大可以适当增大过孔,或者多加几个过孔 线宽大小:小信号线8mil,大电流线不等按1A电流30mil ...

  6. Mego(07) - 关系配置

    这个是本框架的重要功能,该关系就是指对象中的复杂对象或集合属性,该关系与EF中的关系是有区别的.EF中强调关系的成对出现,这是由于数据库关系的思想决定的.然而Mego更接近与对象化逻辑,我们只关心当前 ...

  7. 算法题丨3Sum Closest

    描述 Given an array S of n integers, find three integers in S such that the sum is closest to a given ...

  8. Python内置函数(23)——dict

    英文文档: class dict(**kwarg) class dict(mapping, **kwarg) class dict(iterable, **kwarg) Return a new di ...

  9. setInterval()使用时易疏忽的点

    举个例子: 一道题目 这两个程序的区别就在于我向setInterval的参数一function写入了参数.这就是导致运行结果不尽如人意的原因. setInterval()方法可以接收三个参数,此参数会 ...

  10. vue.js+socket.io+express+mongodb打造在线聊天[二]

    vue.js+socket.io+express+mongodb打造在线聊天[二] 在线地址观看 http://www.chenleiming.com github地址 https://github. ...