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. C/C++中static关键词的作用

    1.在函数体内的static变量作用范围是该函数体,其只被内存分配一次,所以在下次调用的时候会保持上一次的值. 2.模块内的static全局变量可以被模块内的所有函数访问,但不能被模块外的函数访问. ...

  2. 函数buf_LRU_free_from_unzip_LRU_list

    /******************************************************************//** Try to free an uncompressed ...

  3. 函数fsp_alloc_seg_inode

    从inode page中申请inode entry inode = fsp_alloc_seg_inode(space_header, mtr); /************************* ...

  4. DataTable导出到Excel(.NET 4.0)

    最近在论坛里又看到很多关于DataTable(DataSet)导入Excel的帖子,我也温故知新一下,用VS2010重新整理了一个Sample.这个问题简化一下就是内存数据到文件,也就是遍历赋值,只不 ...

  5. 声明顺序 (Bootstrap 编码规范)

    相关的属性声明应当归为一组,并按照下面的顺序排列: Positioning Box model Typographic Visual 由于定位(positioning)可以从正常的文档流中移除元素,并 ...

  6. c#中单元测试

    从走进.net后发现每天有写不完的代码,有做不完的测试...人感觉都已经机械,我们需要认清自己调整好心态,问下自己是否真的喜欢编程.我的答案当然也就是我爱编码,编码给我带来了许多欢乐,每天都给我体验小 ...

  7. STL sort()函数

    C++之所以得到这么多人的喜欢,是因为它既具有面向对象的概念,又保持了C语言高效的特点.STL 排序算法同样需要保持高效.因此,对于不同的需求,STL提供的不同的函数,不同的函数,实现的算法又不尽相同 ...

  8. string 常用 方法

    boost::array< char, 16 > header; string(header.begin(),header.end()) std::vector<uchar> ...

  9. 生日小助手V4.0——迁移到Python3

    生日小助手V4.0——迁移到Python3 生日小助手V4.0只支持Linux系统,依赖命令行软件lunar Ubuntu系统安装方法:1.安装lunarsudo apt-get install lu ...

  10. CodeForce---Educational Codeforces Round 3 USB Flash Drives (水题)解题报告

    对于这题明显是用贪心算法来解决问题: 下面贴出笔者的代码: #include<cstdio> #include<iostream> #include<algorithm& ...