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 ...
随机推荐
- I/O多路转接之poll 函数
poll 一.poll()函数: 这个函数是某些Unix系统提供的用于执行与select()函数同等功能的函数,自认为poll和select大同小异,下面是这个函数的声明: #include < ...
- Python 二分查找
(非递归实现) def binary_search(alist, item): first = 0 last = len(alist)-1 while first<=last: midpoint ...
- iOS开发-OC中TabView的编辑
UITableView编辑 1> UITableView 编辑流程 2> UITableView 编辑步骤(四步) ① 第一步 : 让 TableView 处于编辑状态(在按钮点击事件方法 ...
- android 自定义ScrollView实现背景图片伸缩(阻尼效果)
android 自定义ScrollView实现强调内容背景图片伸缩(仿多米,qq空间背景的刷新) 看到一篇文章,自己更改了一下bug: 原文地址:http://www.aiuxian.com/arti ...
- 第三篇:Python字符编码
一 .了解字符编码的知识储备 1计算机基础知识 1.2文本编辑器存取文件的原理(nodepat++,Pycharm,word) #.打开编辑器就打开了启动了一个进程,是在内存中的,所以,用编辑器编写的 ...
- 深入浅出 SSL 管理配置实战
我们生活在一个信息大爆炸的时代,几乎每天都在和互联网打交道,购物.网银转账.支付宝付款.搜索信息.查看邮件.观看视频.微信聊天.上网冲浪.阅读新闻等,无不时时刻刻在和网络打交道.那如何保护网络安全就相 ...
- New UWP Community Toolkit - ImageEx
概述 UWP Community Toolkit 中有一个图片的扩展控件 - ImageEx,本篇我们结合代码详细讲解 ImageEx 的实现. ImageEx 是一个图片的扩展控件,包括 Ima ...
- EasyUi中对话框。
html页面代码: <head id="Head1" runat="server"> <meta http-equiv="Conte ...
- linux下面的打包压缩命令
tar命令 tar [-cxtzjvfpPN] 文件与目录 ....linux下面压缩之前要把一堆文件打个包再压缩,即使只有一个文件也需要打个包.例子:tar czvf 1.tar.gz hello. ...
- LeetCode & Q414-Third Maximum Number-Easy
Array Math Description: Given a non-empty array of integers, return the third maximum number in this ...