Tree

Time Limit: 1 Sec

Memory Limit: 256 MB

题目连接

http://acm.hust.edu.cn/vjudge/contest/view.action?cid=93850#problem/F

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

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 区间更新的更多相关文章

  1. HDU 1698 线段树 区间更新求和

    一开始这条链子全都是1 #include<stdio.h> #include<string.h> #include<algorithm> #include<m ...

  2. HDU 4348 主席树区间更新

    To the moon Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total ...

  3. hdu 1698 线段树 区间更新 区间求和

    Just a Hook Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  4. HDU(1698),线段树区间更新

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1698 区间更新重点在于懒惰标记. 当你更新的区间就是整个区间的时候,直接sum[rt] = c*(r- ...

  5. HDU 1698 (线段树 区间更新) Just a Hook

    有m个操作,每个操作 X Y Z是将区间[X, Y]中的所有的数全部变为Z,最后询问整个区间所有数之和是多少. 区间更新有一个懒惰标记,set[o] = v,表示这个区间所有的数都是v,只有这个区间被 ...

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

  7. HDU 5002 Tree

    题意: 一棵树  支持删边加边.路径权值加值.路径权值改值.路径求第二大的数字和其个数 思路: LCT的第二题  题意已经把功能都告诉了  比較裸 要注意的是权值加值和改值两个操作的标记下放问题  要 ...

  8. bzoj2631 tree LCT 区间修改,求和

    tree Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 4962  Solved: 1697[Submit][Status][Discuss] Des ...

  9. HDU 3016 线段树区间更新+spfa

    Man Down Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Su ...

随机推荐

  1. MarkupExtension的使用

    记得第一次看到MarkupExtension是在几年前的一次面试中.很不好意思说,当时不知道是什么东东.最近在项目中又用到了WPF的这个功能,决定在博客里记录一下. 在Xaml中为某个对象以Attri ...

  2. Codeforces Round #224 (Div. 2)

    题目:http://codeforces.com/contest/382 A Ksenia and Pan Scales 一个求天平是否能够平衡的题目...水题,注意一下结果的输出就行. #inclu ...

  3. poj1149

    非常好的网络流 每个顾客分别用一个结点来表示. 对于每个猪圈的第一个顾客,从源点向他连一条边,容量就是该猪圈里的猪的初始数量 对于每个猪圈,假设有n个顾客打开过它,则对所有整数i∈[1, n),从该猪 ...

  4. [POJ 2420] A Star not a Tree?

    A Star not a Tree? Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4058   Accepted: 200 ...

  5. 如何从Linux源码获知版本信息

    /*************************************************************************** * 如何从Linux源码获知版本信息 * 声明 ...

  6. Event事件详解

    首先提到event,先要明白event的产生,也要先明白焦点,什么是焦点.焦点 : 使浏览器能够区分用户输入的对象,当一个元素有焦点的时候,那么他就可以接收用户的输入. 我们可以通过一些方式给元素设置 ...

  7. linux chmod 命令详解(转)

    Ubuntu下修改目录权限需要先用 sudo 来获得管理员权限,格式如下: sudo chmod 600 ××× (只有所有者有读和写的权限)sudo chmod 644 ××× (所有者有读和写的权 ...

  8. Jquery Table 的基本操作

    Jquery 操作 Html Table 是很方便的,这里对表格的基本操作进行一下简单的总结. 首先建立一个通用的表格css 和一个 表格Table: table { border-collapse: ...

  9. Visual Studio中的一些较大的文件的作用

    1.sdf 这些是工程中的中间,用于预编译等作用,最终可执行文件是不需要的,默认情况下,删除后重新编译还会生成.如果不需要,在Visual Studio里进入如下设置: 进入"Tools & ...

  10. linux下socket keep alive讲解

    [需求] 不影响服务器处理的前提下,检测客户端程序是否被强制终了.[现状]服务器端和客户端的Socket都设定了keepalive属性.服务器端设定了探测次数等参数,客户端.服务器只是打开了keepa ...