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 ...
随机推荐
- Complete The Pattern #6 - Odd Ladder
Complete The Pattern #6 - Odd Ladder Task: You have to write a function pattern which creates the fo ...
- Visual Studio Developer Command Prompt删除localdb的方法
PM> sqllocaldb.exe stop v11. LocalDB instance "v11.0" stopped. PM> sqllocaldb.exe de ...
- bzoj3940: [Usaco2015 Feb]Censoring
AC自动机.为什么洛谷水题赛会出现这种题然而并不会那么题意就不说啦 .终于会写AC自动机判断是否是子串啦...用到kmp的就可以用AC自动机水过去啦 #include<cstdio> #i ...
- Java [Leetcode 100]Same Tree
题目描述: Given two binary trees, write a function to check if they are equal or not. Two binary trees a ...
- vtiger 支持 物业收费功能 微信收费
谁要?需要什么功能? 直接在下面留言,博主会整理大家的需求,形成产品,发出来.
- NET下RabbitMQ实践[WCF发布篇]
在之前的两篇文章中,主要介绍了RabbitMQ环境配置,简单示例的编写.今天将会介绍如何使用WCF将RabbitMQ列队以服务的方式进行发布. 注:因为RabbitMQ的官方.net ...
- u-boot 环境变量参数设置
今天本来是烧写内核,结果一不小心把uboot也整不能用了,无奈之下只好重新烧个uboot,等都弄好以后,发现系统还是启动不了,原来是启动参数设置不对,于是找到了这篇文章,//是我添加的内容. 原文地址 ...
- 任务栏窗口和状态图标的闪动 z
Demo程序: 实现任务栏窗体和图标的闪动: 整个程序是基于Windows Forms的,对于任务栏右下角状态图标的闪动,创建了一个类型:NotifyIconAnimator,基本上是包装了Windo ...
- grails2.3.11第二课
第二课主要介绍grails相关插件的使用,这是敏捷开发所必需的途径. 可以把grails的插件看作是grails正常项目的迷你型,因为看插件的源码,它的目录结构和正常项目相差无几. 官方开源插件地址 ...
- CDH 5.5.1 Yum源服务器搭建
CDH 5.5.1 Yum源服务器搭建 下载Cloudera Repo #下载资源仓库repo wget https://archive.cloudera.com/cdh5/redhat/6/x86_ ...