HDU 5002 Tree LCT 区间更新
Tree
Time Limit: 1 Sec
Memory Limit: 256 MB
题目连接
http://acm.hust.edu.cn/vjudge/contest/view.action?cid=93850#problem/F
Description
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
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 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
Sample Output
HINT
题意
树上,维护连边,删除边,区间加,区间定值
询问第二大的数是什么,以及有多少个的操作
题解:
LCT模板题
主要是修改pushdown和pushup这两个地方(比较麻烦……
代码:
#include <cstdio>
#include <iostream>
using namespace std;
#define N 300010
const int inf = << ;
typedef pair<int,int>dl;
struct node
{
node *p,*ch[];
int max,rev,val,addv,min;
int max2,ti2,ti1;
int setv;
int size;
}nodes[N],*cur,*null;
int n,m,u,v,w;
node *newnode(int key)
{
cur->p=cur->ch[]=cur->ch[]=null;
cur->max=cur->min=cur->val=key;
cur->max2=cur->min;
cur->ti2=;
cur->ti1=;
cur->rev=;
cur->size=;
cur->setv=-inf;
return cur++;
}
void init()
{
null=nodes;
null->p=null->ch[]=null->ch[]=null;
null->max=null->val=null->max2=-inf;
null->min=inf;
null->ti2=;
null->ti1=;
null->addv=;
null->rev=;
null->setv=-inf;
null->size=;
cur=nodes+;
}
struct dynaminctree
{
bool isroot(node *x)//判根
{
return x==null || x->p->ch[]!=x && x->p->ch[]!=x;
}
void pushup(node *x)
{
x->max = x->val , x->max2 = -inf;x->ti1=;x->ti2 = ;
x->size=; if(x->ch[] != null)
{
x->size += x->ch[]->size;
int mv = x->ch[]->max;
if(mv > x->max)
{
x->max2 = x->max;
x->ti2 = x->ti1;
x->max = mv;
x->ti1 = x->ch[]->ti1;
}
else if(mv == x->max)
{
x->ti1 += x->ch[]->ti1;
}
else if(mv > x->max2)
{
x->max2 = mv;
x->ti2 = x->ch[]->ti1;
}
else if(mv == x->max2)
{
x->ti2 += x->ch[]->ti1;
} mv = x->ch[]->max2;
if(mv != -inf)
{
if(mv > x->max2)
{
x->max2 = mv;
x->ti2 = x->ch[]->ti2;
}
else if(mv == x->max2)
{
x->ti2 += x->ch[]->ti2;
}
}
} //*****************//
if(x->ch[] != null)
{
x->size += x->ch[]->size;
int mv = x->ch[]->max;
if(mv > x->max)
{
x->max2 = x->max;
x->ti2 = x->ti1;
x->max = mv;
x->ti1 = x->ch[]->ti1;
}
else if(mv == x->max)
{
x->ti1 += x->ch[]->ti1;
}
else if(mv > x->max2)
{
x->max2 = mv;
x->ti2 = x->ch[]->ti1;
}
else if(mv == x->max2)
{
x->ti2 += x->ch[]->ti1;
} mv = x->ch[]->max2;
if(mv != -inf)
{
if(mv > x->max2)
{
x->max2 = mv;
x->ti2 = x->ch[]->ti2;
}
else if(mv == x->max2)
{
x->ti2 += x->ch[]->ti2;
}
}
} }
void pushdown(node *x)
{
if(x==null) return;
if(x->rev)
{
x->rev=;
if(x->ch[]!=null) x->ch[]->rev^=;
if(x->ch[]!=null) x->ch[]->rev^=;
swap(x->ch[],x->ch[]);
}
if(x->setv != -inf)
{
if(x->ch[] != null)
{
x->ch[]->max = x->setv , x->ch[]->ti1 = x->ch[]->size;
x->ch[]->max2 = -inf , x->ch[]->ti2 = ;
x->ch[]->setv = x->setv;
x->ch[]->addv = ;
x->ch[]->val = x->setv;
} if(x->ch[] != null)
{
x->ch[]->max = x->setv , x->ch[]->ti1 = x->ch[]->size;
x->ch[]->max2 = -inf , x->ch[]->ti2 = ;
x->ch[]->setv = x->setv;
x->ch[]->addv = ;
x->ch[]->val = x->setv;
}
x->setv = -inf;
} if(x->addv)
{
if(x->ch[] != null)
{
x->ch[]->max += x->addv;
if(x->ch[]->max2 != -inf) x->ch[]->max2 += x->addv;
x->ch[]->addv += x->addv;
x->ch[]->val += x->addv;
} if(x->ch[] != null)
{
x->ch[]->max += x->addv;
if(x->ch[]->max2 != -inf) x->ch[]->max2 += x->addv;
x->ch[]->addv += x->addv;
x->ch[]->val += x->addv;
} x->addv = ;
}
}
void rotate(node *x,int f)
{
if(isroot(x)) return;
node *y=x->p;
y->ch[!f]=x->ch[f];
x->p=y->p;
if(x->ch[f]!=null) x->ch[f]->p=y;
if(y!=null)
{
if(y==y->p->ch[]) y->p->ch[]=x;
else if(y==y->p->ch[]) y->p->ch[]=x;
}
x->ch[f]=y;
y->p=x;
pushup(y);
}
void splay(node *x)
{
static node *sta[N];
int top=;
sta[]=x;
for(node *y=x;!isroot(y);y=y->p)
sta[top++]=y->p;
while (top) pushdown(sta[--top]);
while (!isroot(x))
{
node *y=x->p;
if(isroot(y)) rotate(x,x==y->ch[]);
else
{
int f=y->p->ch[]==y;
if(y->ch[f]==x) rotate(x,!f);
else rotate(y,f);
rotate(x,f);
}
}
pushup(x);
}
node *access(node *u)
{
node *v=null;
while (u!=null)
{
splay(u);
v->p=u;
u->ch[]=v;
pushup(u);
v=u;
u=u->p;
}
return v;
}
node *link(node *u,node *v)//合并
{
access(u);
splay(u);
u->rev=;
u->p=v;
}
node *cut(node *u)//分离
{
access(u);
splay(u);
u->ch[]=u->ch[]->p=null;
pushup(u);
}
void changeroot(node *u)//换根
{
access(u)->rev^=;
}
node *getroot(node *u)//找根
{
access(u);
splay(u);
while (u->p!=null)
{
u=u->p;
}
splay(u);
return u;
}
bool queryuv(node *u,node *v)//判断是否在同一子树
{
while (u->p!=null) u=u->p;
while (v->p!=null) v=v->p;
return u==v;
}
}splay;
int eu[N],ev[N];
int main ()
{
//freopen("in.txt","r",stdin);
int t;scanf("%d",&t);
for(int cas=;cas<=t;cas++)
{
int q;
scanf("%d%d",&n,&q);
init();
for(int i=;i<=n;i++)
{
int a;
scanf("%d",&a);
newnode(a);
}
for(int i=;i<n;i++)
scanf("%d%d",&eu[i],&ev[i]);
for(int i=;i<n;i++)
splay.link(nodes+eu[i],nodes+ev[i]);
printf("Case #%d:\n",cas);
for(int i=;i<=q;i++)
{
scanf("%d",&u);
if(u==)
{
int x,y;
scanf("%d%d",&x,&y);
scanf("%d%d",&u,&v);
splay.changeroot(nodes+x);
splay.cut(nodes+y);
splay.link(nodes+u,nodes+v);
}
else if(u==)
{
scanf("%d%d%d",&u,&v,&w);
splay.changeroot(nodes+u);
splay.access(nodes+v);
node *q=splay.getroot(nodes+v);
q->max=w;
q->val=w;
if(q->max2!=-inf)q->max2=w;
q->setv=w;
}
else if(u==)
{
scanf("%d%d%d",&u,&v,&w);
splay.changeroot(nodes+u);
splay.access(nodes+v);
node *q=splay.getroot(nodes+v);
q->addv+=w;
q->max+=w;
if(q->max2!=-inf)q->max2+=w;
q->val+=w;
}
else
{
scanf("%d%d",&u,&v);
splay.changeroot(nodes+u);
splay.access(nodes+v);
node *q = splay.getroot(nodes+v);
if(q->max2 == -inf) printf("ALL SAME\n");
else printf("%d %d\n",q->max2,q->ti2);
}
}
}
return ;
}
HDU 5002 Tree LCT 区间更新的更多相关文章
- HDU 1698 线段树 区间更新求和
一开始这条链子全都是1 #include<stdio.h> #include<string.h> #include<algorithm> #include<m ...
- HDU 4348 主席树区间更新
To the moon Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total ...
- hdu 1698 线段树 区间更新 区间求和
Just a Hook Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- HDU(1698),线段树区间更新
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1698 区间更新重点在于懒惰标记. 当你更新的区间就是整个区间的时候,直接sum[rt] = c*(r- ...
- HDU 1698 (线段树 区间更新) Just a Hook
有m个操作,每个操作 X Y Z是将区间[X, Y]中的所有的数全部变为Z,最后询问整个区间所有数之和是多少. 区间更新有一个懒惰标记,set[o] = v,表示这个区间所有的数都是v,只有这个区间被 ...
- HDU 5002 Tree(动态树LCT)(2014 ACM/ICPC Asia Regional Anshan Online)
Problem Description You are given a tree with N nodes which are numbered by integers 1..N. Each node ...
- HDU 5002 Tree
题意: 一棵树 支持删边加边.路径权值加值.路径权值改值.路径求第二大的数字和其个数 思路: LCT的第二题 题意已经把功能都告诉了 比較裸 要注意的是权值加值和改值两个操作的标记下放问题 要 ...
- bzoj2631 tree LCT 区间修改,求和
tree Time Limit: 30 Sec Memory Limit: 128 MBSubmit: 4962 Solved: 1697[Submit][Status][Discuss] Des ...
- HDU 3016 线段树区间更新+spfa
Man Down Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Su ...
随机推荐
- Java面试题-并发容器和框架
1. 如何让一段程序并发的执行,并最终汇总结果? 答:使用CyclicBarrier 和CountDownLatch都可以,使用CyclicBarrier 在多个关口处将多个线程执行结果汇总,Coun ...
- bzoj1293
简易贪心+heap 注意要用链表 type link=^node; node=record loc:longint; next:link; end; ...
- 再见WCF
转眼微软的WCF已走过十个年头,它是微软通信框架的集大成者,将之前微软所有的通信框架进行了整合,提供了统一的应用方式.记得从自己最开始做MFC时,就使用过Named Pipe命名管道,之后做Winfo ...
- UVA 10585 Center of symmetry
题意:给出一个点集,问这个集合有没有中心点使点集对称,这个点可以是点集中的点也可以不是点集的点. 解法:一开始我枚举每两个点连线的中点……结果T了orz当时也不知道怎么想的…… 将点按横坐标排序,如果 ...
- Sql2005 全文索引详解
1.前言 14.1 全文索引的介绍 14.2 全文索引中常用的术语 14.3 全文索引的体系结构 14.4 全文目录管理 14.4.1 创建全文目录 14.4.2 查看与修改全文目录 14 ...
- NGINX(七)分段下载
前言 nginx分段下载通过ngx_http_range_filter_module模块进行处理,关于HTTP分段下载过程,可以参考HTTP分段下载一文,主要分为一次请求一段和一次请求多段 涉及数据结 ...
- 168. Excel Sheet Column Title
Excel Sheet Column Title Given a positive integer, return its corresponding column title as appear i ...
- Flash 导出图片和声音
命令文件 PolarBear_jsfl.zip Flash Professional 编辑器命令,用来导出 flash 库中的图片和声音 使用步骤: 1. 首先下载 PolarBear_jsfl.zi ...
- 【转载】 Linux用户态和内核态
[说明]转载自 http://my.oschina.net/liubin/blog/27795 究竟什么是用户态,什么是内核态,这两个基本概念以前一直理解得不是很清楚,根本原因个人觉得是在于因为大部分 ...
- 用Java实现一个通用并发对象池
这篇文章里我们主要讨论下如何在Java里实现一个对象池.最近几年,Java虚拟机的性能在各方面都得到了极大的提升,因此对大多数对象而言,已经没有必要通过对象池来提高性能了.根本的原因是,创建一个新的对 ...