HDU5002--Tree(LCT)

MATLAB去雾算法实战:5种经典方法对比+1种改进方案(附完整源码) 本文详细对比了MATLAB中5种经典去雾算法(包括暗通道先验、多尺度Retinex等)的实现效果,并提出一种创新的自适应融合改进方案。通过完整的源码展示和性能对比,帮助开发者掌握图像去雾的核心技术,提升计算机视觉应用中的图像质量。特别针对去雾算法中的光晕效应问题,给出了工程实践中的优化技巧。 阅读详情
Problem 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
Link-Cut-Tree模板。。。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define maxn 300800
#define inf 0x3f3f3f3f
int first[maxn],nxt[maxn],vv[maxn];
int e;
void Init()
{
    e = 0;
    memset(first,-1,sizeof(first));
}

void addedge(int u,int v)
{
    vv[e] = v;    nxt[e] = first[u];    first[u] = e++;
    vv[e] = u;    nxt[e] = first[v];    first[v] = e++;
}

inline int max(int a,int b)
{
    return a>b?a:b;
}
inline int max(int a,int b,int c)
{
    if(a<b) a = b;
    if(a<c) a = c;
    return a;
}
void scanf_f(int & a)
{
	a = 0;
	bool ok = 0;
	char c;
	while((c = getchar()) < '0' || c > '9')
	{
		if(c == '-')	ok = 1;
	}
	a = c - '0';
	while((c = getchar()) >= '0' && c <= '9')
		a = a*10 + c - '0';
	if(ok)	a = -a;
}
struct Link_Cut_Tree
{
    int key[maxn],pre[maxn],ch[maxn][2],flip[maxn],add[maxn],set[maxn],size[maxn],root[maxn],fa[maxn];
    int maxkey[maxn][2],num[maxn][2],stk[maxn];
    void init()
    {
        root[0] = size[0] = add[0] = ch[0][0] = ch[0][1] = flip[0] = key[0] = pre[0] = fa[0] = 0;
        maxkey[0][0] = maxkey[0][1] = set[0] = -inf;
        num[0][0] = num[0][1] = 0;
    }
    
	void NewNode(int r,int father,int k)
    {
        num[r][0] = 1;num[r][1] = 0;
        maxkey[r][0] = k;    maxkey[r][1] = -inf;
        root[r] = 1;
        key[r] = k;
        size[r] = 1;
        fa[r] = father;
        ch[r][0] = ch[r][1] = add[r] = flip[r] = pre[r] = 0;
        set[r] = -inf;
    }
    
    void PushTo(int x)
    {
        int rear = 0;
        while(x)
        {
            stk[rear++] = x;
            x = pre[x];
        }
        for(int i = rear-1;i >= 0;i--)    PushDown(stk[i]);
    }

    void PushDown(int x)
    {
        if(set[x] != -inf)
        {
            Update_Set(ch[x][0],set[x]);
            Update_Set(ch[x][1],set[x]);
            set[x] = -inf;
        }
        if(add[x])
        {
            Update_Add(ch[x][0],add[x]);
            Update_Add(ch[x][1],add[x]);
            add[x] = 0;
        }
        if(flip[x])
        {
            Update_Rev(ch[x][0]);
            Update_Rev(ch[x][1]);
            flip[x] = 0;
        }
    }

    void PushUp(int x)
    {
        int l = ch[x][0],r = ch[x][1];
        //维护size,cnt,maxkey[x][0],maxkey[x][1],num[x][0],num[x][1].
        size[x] = 1 + size[l] + size[r];
        int a = max(key[x],maxkey[l][0],maxkey[r][0]);
        int numa = 0;
        int b = -inf;
        if(key[x] != a)
            b = max(key[x],b);
        if(maxkey[l][0] == a)
            b = max(maxkey[l][1],b);
        else b = max(maxkey[l][0],b);
        if(maxkey[r][0] == a)
            b = max(maxkey[r][1],b);
        else b = max(maxkey[r][0],b);
        int numb = 0;
        if(key[x] == b)    numb += 1;
        if(maxkey[l][0] == b)    numb += num[l][0];
        if(maxkey[l][1] == b)    numb += num[l][1];
        if(maxkey[r][0] == b)    numb += num[r][0];
        if(maxkey[r][1] == b)    numb += num[r][1];
        if(key[x] == a)    numa += 1;
        if(maxkey[l][0] == a)    numa += num[l][0];
        if(maxkey[r][0] == a)    numa += num[r][0];
        maxkey[x][0] = a;
        maxkey[x][1] = b;
        num[x][0] = numa;
        num[x][1] = numb;
        if(b == -inf)    num[x][1] = 0;
    }

    void Update_Rev(int x)
    {
        swap(ch[x][0],ch[x][1]);
        flip[x] ^= 1;
    }

    void Update_Set(int x,int a)
    {
        if(!x)    return;
        add[x] = 0;
        key[x] = a;
        set[x] = a;
        maxkey[x][0] = a;
        num[x][0] = size[x];
        maxkey[x][1] = -inf;
        num[x][1] = 0;
    }
    
	
	void Update_Add(int x,int a)
    {
        if(!x)    return;
        add[x] += a;
        key[x] += a;
        maxkey[x][0] += a;
        if(maxkey[x][1] != -inf)
            maxkey[x][1] += a;
    }
    
    void Rotate(int x,int kind)
    {
        int y = pre[x];
        //PushDown(y);
        //PushDown(x);
        ch[y][!kind] = ch[x][kind];
        if(ch[x][kind])	
			pre[ch[x][kind]] = y;
        if(pre[y])
            ch[pre[y]][ch[pre[y]][1]==y] = x;
        pre[x] = pre[y];
        ch[x][kind] = y;
        pre[y] = x;
        PushUp(y);
        
        if(root[y])
        {
            root[y] = 0;
            root[x] = 1;
            fa[x] = fa[y];
            fa[y] = 0;
        }    
    }

    void Splay(int r)
    {
        PushTo(r);
        while(pre[r] != 0)
        {
            int y = pre[r],z = pre[y];
            //PushDown(z);    PushDown(y);    PushDown(r);
            if(z == 0)
            {
                Rotate(r,ch[y][0]==r);        
            }
            else 
            {
                int kind = (ch[z][0] == y);
                if(ch[y][kind] == r)
                {
                    Rotate(r,!kind);
                    Rotate(r,kind);
                }
                else 
                {
                    Rotate(y,kind);
                    Rotate(r,kind);
                }
            }
        }
        PushUp(r);
    }
    
    int Access(int x)
    {
        int c = 0;
        while(x)
        {
            Splay(x);
            if(ch[x][1])
            {
                fa[ch[x][1]] = x;
                Is_Root(ch[x][1]);
            }
            ch[x][1] = c;
            if(c)
			{
                pre[c] = x;
				fa[c] = 0;
			}
            root[c] = 0;
            c = x;    x = fa[x];
        }
        return c;
    }

    void Make_Root(int x)
    {
        Access(x);
        Splay(x);
        Update_Rev(x);
    }
    
    void Is_Root(int x)
    {
        root[x] = 1;
        pre[x] = 0;
    }

    void Link(int u,int v)
    {
        if(u == v)    return;
        Make_Root(u);
        Access(v);
        Splay(v);
        if(pre[u] == 0)    fa[u] = v;
    }

    void Cut(int u,int v)
    {
        Make_Root(u);
        Access(v);
        Splay(v);
        if(pre[u])
        {
            if(ch[v][0])
				Is_Root(ch[v][0]);
            fa[ch[v][0]] = 0;
            ch[v][0] = 0;
            Is_Root(v);
            fa[v] = 0;
            PushUp(v);
        }
    }

    void Update_Set_UtoV(int u,int v,int w)
    {
        Make_Root(u);
        Access(v);
        Splay(v);
        if(u == v || pre[u] != 0)    Update_Set(v,w);
    }

    void Update_Add_UtoV(int u,int v,int w)
    {
        Make_Root(u);
        Access(v);
        Splay(v);
        if(u == v || pre[u] != 0)    Update_Add(v,w);
    }

    void Query(int u,int v)
    {
        if(u == v)
        {
            printf("ALL SAME\n");
            return;
        }
        Make_Root(u);
        Access(v);
        Splay(v);
        if(pre[u])
        {
            if(num[v][1]==0)    printf("ALL SAME\n");
            else printf("%d %d\n",maxkey[v][1],num[v][1]);
        }

    }
    void dfs(int u,int pre)
    {
        NewNode(u,pre,key[u]);
        for(int i = first[u];i != -1;i = nxt[i])
        {
            int v = vv[i];
            if(v == pre)    continue;
            dfs(v,u);
        }

    }

    void solve(int n,int m)
    {
        init();
        for(int i = 1;i <= n;i++)
            //scanf("%d",&key[i]);
			scanf_f(key[i]);
        for(int i = 1;i < n;i++)
        {
            int u,v;
            //scanf("%d%d",&u,&v);
			scanf_f(u);
			scanf_f(v);
            addedge(u,v);
        }
        dfs(1,0);
        while(m--)
        {
            int ope;    //scanf("%d",&ope);
			scanf_f(ope);
            if(ope == 1)
            {
                int x,y,a,b;
                //scanf("%d%d%d%d",&x,&y,&a,&b);
				scanf_f(x);
				scanf_f(y);
				scanf_f(a);
				scanf_f(b);
                Cut(x,y);
                Link(a,b);
            }
            else if(ope == 2)
            {
                int a,b,x;
                //scanf("%d%d%d",&a,&b,&x);
				scanf_f(a);
				scanf_f(b);
				scanf_f(x);
                Update_Set_UtoV(a,b,x);
            }
            else if(ope == 3)
            {
                int a,b,d;
                //scanf("%d%d%d",&a,&b,&d);
				scanf_f(a);
				scanf_f(b);
				scanf_f(d);
                Update_Add_UtoV(a,b,d);
            }
            else 
            {
                int a,b;
                //scanf("%d%d",&a,&b);
				scanf_f(a);
				scanf_f(b);
                Query(a,b);
            }
        }

    }
}lct;

int main()
{
    //freopen("in.txt","r",stdin);
    int t,cas = 0;
    scanf_f(t);
	//scanf("%d",&t);
    while(t--)
    {
        Init();
        int n,m;
        //scanf("%d%d",&n,&m);
		scanf_f(n);
		scanf_f(m);
		printf("Case #%d:\n",++cas);
        lct.solve(n,m);
    }
}


(持续更新中!)详解【计算机类&面试真题】军队文职考试 ——第二期(真题+解析)| 网络协议的三个核心要素;交互式系统中的非剥夺策略;中断和陷入的区别;可变分区管理中的硬件机制;数据库系统的优点 本篇博客将讨论军队文职面试(计算机类)的几个关键问题。我们将介绍网络协议的核心要素(帮助你理解网络通信的基本原理)、交互式系统中的非剥夺策略(解释为何这是一个优秀的策略以及其对用户体验、系统稳定性和可预测性的影响)、中断和陷入的区别(从引起原因、处理机制、权限级别和应用等方面进行阐述)、可变分区管理的硬件机制以及数据库系统与文件系统的优点比较。通过阅读本文,您将深入了解这些话题,为面试准备和实际应用提供有价值的知识。 阅读详情

相关推荐

Allegro规则管理器实战:5步搞定Xnet等长组设置(含Relative Propagation Delay配置)

本文详细介绍了在Cadence Allegro规则管理器中,通过5个实战步骤高效设置Xnet等长组的方法。核心内容包括创建Xnet属性、定义引脚对、建立匹配组,并重点讲解了Relative Propagation Delay规则的配置与应用,帮助PCB设计师确保高速信号时序对齐,提升系统稳定性与性能。

weixin_29193259的博客 518

洛谷 P3690 【模板】Link Cut Tree (动态树)LCT

题目描述给定n个点以及每个点的权值,要你处理接下来的m个操作。操作有4种。操作从0到3编号。点从1到n编号。0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor和。保证x到y是联通的。1:后接两个整数(x,y),代表连接x到y,若x到y已经联通则无需连接。2:后接两个整数(x,y),代表删除边(x,y),不保证边(x,y)存在。3:后接两个整数(x,y),代表将点x上的权值变成y。

liangzihao1的博客 374

集成库仑计移动电源设计:从原理到实战,实现精准电量管理

在电池供电设备中,精准的电量计量是提升用户体验和产品可靠性的核心技术。传统基于电压估算的方法因受温度、负载和老化影响误差较大,而库仑计技术通过直接测量充放电电流并对时间积分,实现了电荷量的直接计量,从根本上提升了精度。这项技术的核心价值在于为设备提供了真实、可靠的电量状态数据,是智能电池管理系统的基础。其应用场景广泛,从消费电子如移动电源、智能穿戴,到工业与汽车领域如储能系统、新能源汽车的电池管理都不可或缺。本文以移动电源为例,深入解析了集成库仑计方案的硬件设计要点,特别是围绕高精度采样电阻与差分放大器的电

weixin_33453726的博客 551

动态树 Link Cut Tree【模板】【LCT】

>Link luogu P3690 >Description 给定 n 个点以及每个点的权值,要你处理接下来的 m 个操作。 操作有四种,操作从 0 到 3 编号。点从 1 到 n 编号。 x y 代表询问从 x 到 y 的路径上的点的权值的 xor 和。保证 x 到 y 是联通的。 x y 代表连接 x 到 y,若 x 到 y 已经联通则无需连接。 x y 代表删除边 (x,y),不保证边 (x,y) 存在。 x y 代表将点 x 上的权值变成 y。 n≤105,m≤3∗105n\le1

//(^ o ^)// 230

Polyworks脚本开发学习笔记(一)-脚本开发环境

详细的总结和记录了利用Polyworks进行脚本开发的一些方法和心得

qq_43662503的博客 6800

Centos7安装NVIDIA驱动并在docker容器中使用GPU

Centos7安装NVIDIA驱动并在docker容器中使用GPU

运维giao的博客 2084

2014鞍山网络预选赛1006(LCT模板题)hdu5002

Tree Time Limit: 16000/8000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 41    Accepted Submission(s): 10 Problem Description You are given a tree wit

cq_phqg 2017

如何设计ADAS系统功能状态机(一)

状态机模块在自动驾驶系统中扮演着关键的角色,它负责管理和控制各个功能的状态转换和行为执行。今天我们来聊聊如何设计自动驾驶系统的状态机。

supass2018的博客 1615

hdu5002

因为脑袋有坑,坑了自己一天。 记不清是当初看的谁的代码写出来的了,如果有发现相似的,请留言,我会及时添加链接。 (今天和队友一起出去吃魏家凉皮,因为忘了说带走,结果自己一个人留在那里吃完的;麻酱味的凉皮,不如秘制凉皮好吃,虽然秘制凉皮很辣!) #include<stdio.h> #include<string.h> #include<iostr...

164

13、HTML 表格创建与样式设置全攻略

本文全面介绍了HTML表格的创建与样式设置方法,涵盖表格行列添加、边框控制、行和列分组(thead、tbody、tfoot、colgroup)、宽度与高度设置、内边距与间距调整,以及表格对齐方式。同时提供了最佳实践建议、常见问题解决方案及综合示例代码,帮助开发者构建结构清晰、样式美观且兼容性强的HTML表格。

blue的专栏 97

SAP使用XCO框架创建RAP所有对象

通过XCO框架自动生成SAP ABAP开发对象。

DeveloperMrMeng的博客 550

HDU 5002 Tree

题意: 一棵树  支持删边加边、路径权值加值、路径权值改值、路径求第二大的数字和其个数 思路: LCT的第二题  题意已经把功能都告诉了  比较裸 要注意的是权值加值和改值两个操作的标记下放问题  要先down改值  再down加值 对于路径的操作通过mroot变换树的形态再access拿出路径比较方便  不要像我上一篇一样搞lca 代码: #include #include #in

House 1503

Openclaw 错误分析 与 解决方案 之:Selected model is at capacity. Try a different model, or wait and retry.

Openclaw 错误分析 与 解决方案 :Selected model is at capacity. Try a different model, or wait and retry.

多媒体编程、网络编程、系统编程、网络安全编程、驱动编程 6421

hdu 5002 Tree(LCT裸题)

题目链接:hdu 5002 Tree 题意: 给你一棵树,每个节点有个权值。 现在有四种操作 1. 删一条边加一条边,保证操作后还是一棵树。 2. 将一条链的节点的权值设为x. 3. 将一条链的节点的权值加上x. 4. 询问一条链的第二大权值,并且输出有多少个。 题解: 很裸的LCT,维护一下就行了。 1 #include<bits/stdc++.h> ...

weixin_30521649的博客 184

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

LCT - hdu5002 Tree

题目: http://acm.hdu.edu.cn/showproblem.php?pid=5002 题意: 给一棵树树,提供四种操作 1:删除(x,y)边,添加(a,b)边,保证操作前后都是合法的树 2:修改a--b路径上所有点的权值为x 3:a--b路径上所有点的权值增加d 4:输出a--b路径上的第二大值及出现的次数,这里的第二大指的为严格第二大,即1 1 2 2

Keith_windniw的专栏 530

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

「hdu5002」Tree【LCT】

Tree Time Limit: 16000/8000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 1444 Accepted Submission(s): 586 Problem Description You are given a tree with NNN nod...

wzw 196

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

hdu 5002 Tree (LCT)

hdu 5002 Tree (LCT) 几乎是模板题,维护一个最大值和次大值即可。 代码:

No__stop 1063

hdu5002:Tree (LCT)

题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=5002 题目大意:一开始给你一棵有N个点的树(N 题目分析:编程一中午,码出动态树。——第一道LCT 这题算是LCT的半裸题吧。前面的操作都很简单,但是我们如何知道一条链上第二大的数有几个呢?我想先求出第二大的数是几,然后搞一棵可持久化线段树之类乱七八糟脑洞大开地维护每一个数在每一条链上出现几次

KsCla 504

HDU5002:Tree(LCT)

Description Input Output Sample Input Sample Output Solution 写了$6k$有点自闭…… 一操作加边断边,二操作路径覆盖,三操作路径加,四操作求路径次大值和次大值个数。 记得讨论好覆盖标记和加标记的关系……再维护下最大值,最大值个数,次大值和次大值个数就好了。 码农题也没什么好说的…… Code ...

weixin_34341229的博客 118

HDU5002 Tree(LCT)

今天做了一道LCT模板题之后忽然间好像记起来LCT的模板怎么用了,于是就把上次网络赛的一道LCT补一下。典型的删边,加边操作,还有路径加和路径set为一个数。维护的是路径第二大以及它有多少个,后来想想其实确实是挺好写的,就是维护最大值以及次大值,然后upd的时候把儿子合并回去就好了,当时觉得不会做实在是想太多了。 #pragma warning(disable:4996) #in...

weixin_30466039的博客 119

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 You are given a tree with N nodes which a...

weixin_34343689的博客 129

hdu5002 tree LCT

又是不小心打错一个字符调了一晚上。。。 #include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #define REP(i,a,b) for(int i=a;i<=b;i++) #de...

weixin_30781775的博客 117

【HDU】5002 Tree 动态树模板题

传送门:【HDU】5002 Tree

poursoul 983

LCT link-cut tree Hdu 5002 Tree 2014鞍山网络赛

#include #include #include #include using namespace std; #define maxn 300007 #define inf 1000000000 struct Node{ Node *fa,*ch[2]; bool rev,root; int val,add,set,size; int max[2],num[2

G.D.Retop的专栏 920

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 is associated with an integer as the weight.Your task is to deal with M operations of 4 types:1.De...

weixin_30699831的博客 143

HDU 5002 Tree (2014年鞍山赛区网络赛F题)

1.题目描述:点击打开链接 2.解题思路:LCT的模板题 3.代码: #include #include #include #include #include using namespace std; const int N = 111111; const int INF = 1111111111; int n, m; class LCT { private :

Skyline 1237
上一篇: CF468B--Two Sets
下一篇: HDU5029--Relief grain(树链剖分)
SCUT_Pein
博客等级 码龄14年 54粉丝 480原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值