POJ 3237 Tree (树链剖分+线段树)

ESP32S3接入讯飞在线语音识别教程及配套源代码 本文介绍了如何使用ESP32-S3开发板实现讯飞在线语音识别功能。首先,需要准备硬件设备,包括ESP32-S3开发板、麦克风模块、MicroSD卡模块和扬声器模块。接着,安装Arduino IDE并配置ESP32-S3开发环境,注册讯飞开放平台账号并获取API凭证。然后,通过I2S接口连接麦克风模块,并编写代码实现语音录制、Base64编码、API请求和识别结果处理。代码包括初始化WiFi、麦克风、系统时间,以及录制语音、发送请求、解析响应等功能。最后,通过按键触发录音,并将识别结果输出到串口。 阅读详情

题意:

http://poj.org/problem?id=3237

给一棵树,操作三种 



CHANGE i vChange the weight of the ith edge to v
NEGATE a bNegate the weight of every edge on the path from a to b
QUERY a bFind the maximum weight of edges on the path from a to b


解决:

树链剖分模版题,先把树上的结点根据重链轻链分解成一个个连续的区间,把每个节点的编号映射到 一个数组p[]


对于查询(a,b)的操作,则从a,b出发,不断查询区间【a,top(a)】的某些值,然后a指向fa(top[a]),直到a,b的top一样,也即在同一条链上,在进行最后一次查询。

这里线段树阶段x记录的是x到fa(x)的边的边权。


所以change和query操作都变成在线段树的操作了,而negate则直接交换区间最大最小值即可。


#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;

const int MAXN = 100010;
struct Edge
{
    int to,next;
} edge[MAXN*2];
int head[MAXN],tot;
int top[MAXN];//top[v]表示v所在的重链的顶端节点
int fa[MAXN]; //父亲节点
int deep[MAXN];//深度
int num[MAXN];//num[v]表示以v为根的子树的节点数
int p[MAXN];//p[v]表示v与其父亲节点的连边在线段树中的位置
int fp[MAXN];//和p数组相反
int son[MAXN];//重儿子
int pos;
void init()
{
    tot = 0;
    memset(head,-1,sizeof(head));
    pos = 0;
    memset(son,-1,sizeof(son));
}
void addedge(int u,int v)
{
    edge[tot].to = v;
    edge[tot].next = head[u];
    head[u] = tot++;
}
void dfs1(int u,int pre,int d) //第一遍dfs求出fa,deep,num,son
{
    deep[u] = d;
    fa[u] = pre;
    num[u] = 1;
    for(int i = head[u]; i != -1; i = edge[i].next)
    {
        int v = edge[i].to;
        if(v != pre)
        {
            dfs1(v,u,d+1);
            num[u] += num[v];
            if(son[u] == -1 || num[v] > num[son[u]])
                son[u] = v;
        }
    }
}
void getpos(int u,int sp) //第二遍dfs求出top和p
{
    top[u] = sp;
    p[u] = ++pos;
    fp[p[u]] = u;
    if(son[u] == -1) return;
    getpos(son[u],sp);
    for(int i = head[u] ; i != -1; i = edge[i].next)
    {
        int v = edge[i].to;
        if(v != son[u] && v != fa[u])
            getpos(v,v);
    }
}
struct TREE
{
    int  maxx[4*MAXN],minn[4*MAXN],ne[4*MAXN] ;
    void build(int l,int r,int i)    //  线段树的建立;
    {
        ne[i]=0;    //ne[rt]=aa[++ok];
        maxx[i]=minn[i]=0;
        if(l==r) return;
        int mid=(l+r)>>1;
        build(l,mid,i<<1);
        build(mid+1,r,i<<1|1);
    }
    void pushDown(int i, int l, int r)		//把i节点的延迟标记传递到左右儿子节点
    {
        if(ne[i] != 0)
        {
            int mid = (l + r) >> 1;
            maxx[i << 1]  = -maxx[i << 1];
            minn[i << 1]  = -minn[i << 1];
            swap(minn[i << 1],maxx[i << 1]);
            maxx[i << 1|1]  = -maxx[i << 1|1];
            minn[i << 1|1]  = -minn[i << 1|1];
            swap(minn[i << 1|1],maxx[i << 1|1]);

            ne[i << 1] ^= 1;
            ne[i << 1 | 1]^= 1;
            ne[i] = 0;
        }
    }
    void update_ne(int i,int l,int r,int ql,int qr)
    {
        if(l > qr ||ql > r)		//更新区间不在当前区间内
            return ;
        if(l >=ql && r <=qr )	//要更新的区间把当前区间完全包括,则把当前整个区间+val,然后返回上一层
        {
            maxx[i]  =   -maxx[i];
            minn[i]  =   -minn[i];
            swap(maxx[i],minn[i]);
            ne[i]^=1;
            return ;
        }
        pushDown(i, l, r);			//如果上面没reutrn 表示要往左右儿子区间查询,所以把延迟标记放下去
        int mid = (l + r) >> 1;
        update_ne(i << 1, l, mid, ql, qr);
        update_ne(i << 1 | 1, mid + 1, r, ql, qr);
        maxx[i] = max(maxx[i << 1] , maxx[i << 1 | 1]);
        minn[i] = min(minn[i << 1] , minn[i << 1 | 1]);
    }
    void update(int i, int l, int r, int x, int val) //更新区间为qlqr,当前区间为l,r,代表当前区间和的节点为i,更新值为val,
    {
        if(l > x ||x > r)		//更新区间不在当前区间内
            return ;
        if(l ==x && r ==x )	//要更新的区间把当前区间完全包括,则把当前整个区间+val,然后返回上一层
        {
            maxx[i]  =   val;
            minn[i]  =   val;
            ne[i]=0;
            return ;
        }
        pushDown(i, l, r);			//如果上面没reutrn 表示要往左右儿子区间查询,所以把延迟标记放下去
        int mid = (l + r) >> 1;
        update(i << 1, l, mid, x, val);
        update(i << 1 | 1, mid + 1, r, x, val);
        maxx[i] = max(maxx[i << 1] , maxx[i << 1 | 1]);
        minn[i] = min(minn[i << 1] , minn[i << 1 | 1]);
    }

    int query(int i, int l, int r, int ql, int qr)	 //查询区间为qlqr,当前区间为l,r,代表当前区间和的节点为i
    {
        if(l > qr || ql > r)
            return -2e9;
        if(l >= ql && r <= qr)
            return maxx[i];
        pushDown(i, l, r);				//同update
        int mid =( l + r) >> 1;
        return max(query(i << 1, l, mid, ql, qr)
               ,query(i << 1 | 1, mid + 1, r, ql, qr));

    }

    int findmax(int u,int v)//查询u->v链的最大值
    {
        int f1=top[u],f2=top[v];
        int tmp=-1e9;
        while(f1!=f2)
        {
            if (deep[f1]<deep[f2])
            {
                swap(f1,f2);
                swap(u,v);
            }
            tmp=max(tmp,query(1,1,pos,p[f1],p[u]));
            u=fa[f1],f1=top[u];
        }
        if (u==v) return tmp;
        if (deep[u]>deep[v] ) swap(u,v);
        return max(tmp, query(1,1,pos,p[son[u]],p[v])); //son[u]是u到fu的边权
    }
    void Negate(int u,int v)
    {
        int f1=top[u],f2=top[v];
        while(f1!=f2)
        {
            if (deep[f1]<deep[f2])
            {
                swap(f1,f2);
                swap(u,v);
            }
            update_ne(1,1,pos,p[f1],p[u]);
            u=fa[f1],f1=top[u];
        }
        if (u==v) return ;
        if (deep[u]>deep[v])swap(u,v);
        return update_ne(1,1,pos,p[son[u]],p[v]);
    }

};
TREE tp;
int e[MAXN][3];

int main()
{

    int n;

    int t;


    cin>>t;
    while(t--)
    {

        init();
        scanf("%d",&n);
        for (int i=0; i<n-1; i++)
        {
            scanf("%d%d%d",&e[i][0],&e[i][1],&e[i][2]);
            addedge(e[i][0],e[i][1]);
            addedge(e[i][1],e[i][0]);
        }
        dfs1(1,0,0);
        getpos(1,1);
         tp.build(1,pos,1);
       // build(1,1,pos);
        for (int i=0; i<n-1; i++)
        {
            if (deep[e[i][0]]>deep[e[i][1]])
                swap(e[i][0],e[i][1]);
            tp.update(1,1,pos,p[e[i][1]],e[i][2]); //son->fa的边权为e[i][2]
        }
        char op[10];
        int u,v;
        while(scanf("%s",op))
        {
            if (op[0]=='D') break;
            scanf("%d%d",&u,&v);
            if (op[0]=='Q')
                printf("%d\n",tp.findmax(u,v));
            else if (op[0]=='C')
                tp.update(1,1,pos,p[e[u-1][1]],v);
            else tp.Negate(u,v);
        }

    }
    return 0;

}




CHANGE

 i v
Change the weight of the ith edge to v
NEGATE a bNegate the weight of every edge on the path from a to b
QUERY a bFind the maximum weight of edges on the path from a to b

Input

Probability and Statistics - 4th edition 立即下载

相关推荐

Dify 从入门到熟悉100 天的学习大纲

理解 Dify 的核心概念,熟悉操作界面,并能创建简单的 AI 应用。祝你在这 100 天的旅程中学有所成,成为一名优秀的 AI 应用开发者!掌握生产环境部署、监控、调优,并关注 Dify 生态和前沿动态。探索多模态、Agent、API 集成、性能优化等高级主题。掌握工作流编排、高级提示词技巧、知识库优化等核心功能。

IT深耕十余载,大道之简 1735

POJ 3237 Tree(边树剖)

这个题比较难是因为,有一个区间取反操作,(好吧,还是我菜) 求一个区间的最大值,若区间内所有的数都变成原来的负数形式,那么其最小值就成为了最大值 还有一点就是在树剖中的点权变为了边权,因为这样,在单边修改的时候,要找对应边上深度较大的点(代码中的注释 1),在区间修改时,要忽略掉他们的 LCA ,因为在退出 while 循环后,x,y 两点跳到同一条重链上,深度最小的那个点就是 LCA const int N=1e5+5; int n,m,t; int i,j,k; ...

C_Dreamy的博客 504

Zabbix Trigger actions访问出现500

本篇博客详细介绍了Zabbix访问'Trigger actions'出现的错误状况,访问界面出现500,并提供了解决方案。

格子的博客 562

POJ3237树链剖分

CHANGE i v Change the weight of the ith edge to v NEGATE a b Negate the weight of every edge on the path from a to b QUERY a b Find the maximum weight of edges on the path from a to b

老李2009 340

【软碟通 | UltraISO】刻录光盘教程(制作U盘启动盘)

前言 今天老师说办公室的电脑有点卡,让我给重新安装一个 Windows 7 系统。于是就用软碟通(UltraISO)在 U 盘上刻录了一个 Windows 7 镜像,然后给老师重装了系统。顺便把制作 U 盘启动盘的教程也分享给大家。 软件 UltraISO v9.7.1.3519:点击跳转(密码:dd2k) 教程 将 U 盘插到电脑上,然后鼠标右击选择格式化(制作启动盘必须格式化) 点击文件-打开 选择下载好的系统镜像(如:Windows 7) 点击启动-写入硬盘映像 选择硬盘

XavierJ的博客 2万+

【科学文献计量】标准参考出版年谱(Standard RPYS)和多维参考出版年谱(Multi RPYS)

@[TOC](标准参考出版年谱(Standard RPYS)和多维参考出版年谱(Multi RPYS)) 1 标准参考出版年谱与多维参考出版年谱 1.1 标准参考出版年谱(Standard RPYS) 标准参考出版年谱(Standard Reference Publication Year Spectroscopy)是由Marx, Bornmann, Barth, and Leydesdorff(2014)和Marx and Bornmann(2014)提出的一种量化历史出版物对研究领域影响的方法。该方法通

lys_828的博客 1103

树链剖分理解&&poj 3237

树链剖分用一句话概括就是:把一棵树剖分为若干条链,然后利用数据结构(树状数组,SBT,Splay,线段树等等)去维护每一 条链,复杂度为O(logn) 假如 一个树就是一条链的话(极限的想想),我们可以用数据结构(线段树,树桩数组)去维护它。 下图 1-6就是一个链树,用树状数组维护 这个性质很好,维护很方便 然后再画个树,咱们强行用树状数组维

a915800048的专栏 723

Android AVB 分析(十六)5 个例子彻底理解 FEC(Reed-Solomon) 的工作原理

关于 FEC 是如何工作的,一直是我 Android OTA 讨论群中的未解话题,大家基本上都不清楚 Android 上面的 FEC 是如何工作的,为什么在 OTA 升级的最后阶段,FEC 的编码计算会消耗大量的 IO 资源,并持续很长时间。接下来的几篇,我会从一个程序员的角度,演示基于里德所罗门编码的 FEC 到底是如何工作的。

洛奇看世界 667

POJ 3237 树链剖分 题解

POJ3237

onepointo 496

Android 13.0 展讯平台关机充电动画横屏显示修改

在13.0的系统rom定制化开发中,在关于展讯平台的产品中,系统默认的充电动画是竖屏显示的,但是在像平板的产品中竖屏动画肯定不符合规范, 所以需要在平板TV产品中,充电动画同时也是需要修改为横屏显示的,接下来就来分析下充电动画的相关绘制流程,然后实现功能

安卓兼职framework和app工程师的博客 409

从零到一:Python+Playwright 实现动态网站全量数据采集实战(附反爬对抗与性能优化)

在动手之前,先明确武器优势: 2. 项目结构规划 为了代码可维护性,我们采用模块化结构: 三、核心实战:构建动态采集器 第一步:初始化“隐身”浏览器 普通启动容易被检测,我们需要注入一段 JS 脚本来抹除自动化特征。 第二步:处理无限滚动与动态加载 这是动态网站的核心难点。我们需要模拟人类滚动,并等待新数据加载完成。 第三步:登录态保持与复用 避免每次运行都重新登录。我们将 Cookie 保存到本地,下次直接加载。 第四步:主流程编排 将上述模块串联起来,并加入异常重试机制。 四、进阶优化:性能与反爬

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 1162

树链剖分(基于边权,点更新,区间更新)poj3237Tree

Tree Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 4849   Accepted: 1327 Description You are given a tree with N nodes. The tree’s nodes are numbered 1

龙崎的专栏 779

【Flink】FLink session yarn kerberos认证报错 PortUnreachableException: ICMP Port Unreachable

本篇博客是在上一篇博客:【Flink】FLink session yarn kerberos认证报错 KrbException: Cannot locate default realm还没找到原因的时候做的一次尝试。因为项目需要,我们需要对接华为认证的yarn集群,运行flink任务,我们的任务分为两种,yarn pre-job模式和flink session模式。我们在配置文件中配置如下# kerberos认证需要的东西提交任务的脚本如下。

九师兄 1267

「POJ3237」Tree【树链剖分+线段树】

题目链接:http://poj.org/problem?id=3237 Tree Time Limit: 5000MS Memory Limit: 131072K Description You are given a tree with NNN nodes. The tree’s nodes are numbered 111 through NNN and its edges are numbe...

wzw 234

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

poj 3237 Tree 题解(树链剖分,线段树)

原题链接: poj 题意简述 多组数据。给定一个树,带边权,要支持三种操作,分别是: 两个节点之间的路径的边权全部×−1\times -1×−1,即取相反数 单边修改边权值 求两个节点之间路径上的最长边 数据 输入 第一行一个ttt,表示有ttt组数据。对于每一个数据,先有一个nnn,表示点数。然后n−1n-1n−1行,每行两个数a,b,ca,b,ca,b,c表示a,ba,ba,b之间有一个边...

LightningUZ的博客 287

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

树链剖分+线段树 poj3237 Tree

传送门:点击打开链接 题意:3种操作,1单点更新,2路径正负反转,3路径查询最大值 思路:线段树维护最大值和最小值和一个懒惰标记,然后在线段树的基础上用树链剖分维护 #include #include #include #include #include #include #include #include #include #include #include #include #inclu

qwb的博客 856

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

POJ 3237 Tree (树链剖分+线段树)

POJ 3237 Tree题目大意:给你n个结点的树,有三种操作: 1.CHANGE i v 将i号边边权变为v 2.NEGATE a b 将a点到b点路径上的边权取相反数 3.QUERY a b 找到a点到b点路径上的边权的最大值 输出所有3操作结果,指令结束标志为”DONE”. 有多组数据.题目分析:(又滚去做树链剖分的题,元旦放假前开始做到现在,233)将边权转化成相连两点中子节点的

Continue 1041

poj 3237 Tree 树链剖分 线段树

题目链接题意给定一棵树,每条边上都有权值。 三种操作: 1. 修改某条边的权值 2. 将某条树链上所有边的权值变为相反数 3. 询问某条树链上的最大边权思路先树链剖分,然后建线段树,维护一段的最大值和最小值(Lazy TagLazy\ Tag 好题)。Code#include <cstdio> #include <cstring> #include <iostream> #include <

kkkkahlua的博客 324

POJ3237 Tree 树链剖分 线段树

欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - POJ3237 题意概括 Description 给你由N个结点组成的树。树的节点被编号为1到N,边被编号为1到N-1。每一条边有一个权值。然后你要在树上执行一系列指令。指令可以是如下三种之一: CHANGE i v:将第i条边的权值改成v。 NEGATE a b:将点a到点b路径上所有边的...

weixin_30408165的博客 123

【POJ3237】Tree 树链剖分+线段树

【POJ3237】Tree Description You are given a tree withNnodes. The tree’s nodes are numbered 1 throughNand its edges are numbered 1 throughN− 1. Each edge is associated with a weight. Then ...

aodanchui1057的博客 140

poj3237tree【树链剖分入门题+线段树】

休息了两天,今天开始做树链剖分,除了模板长以外,还是挺好理解的。就只是线段树+剖分独特的函数,然后树链剖分所用的数组有点多,没了。其中需要注意的一个点是“链”(路径)不一定是从根节点到叶子节点的,轻儿子这个点它也有重儿子啊啊啊。 再说这个题,单点更新,区间取相反数,区间求最大值。 /*********** poj3237 2015.1.23 2504K 657MS C++ 6396B ****

MissZhou要努力 1628

poj3237--Tree(树链剖分+线段树)

题目链接:poj--3237 题意很简单,给出n个节点的一棵树,有三种操作: 1、C修改第i条边的值为v 2、N改变节点a到b内边的权值的符号(取反) 3、Q询问节点a到b内权值的最大值 首先树链剖分,将边整合到线段树上,线段树数组cl,因为存在取反操作,所以最大值可能是由最小值取反得到,所以记录最大和最小值,cl[i][0]记录第i段的最大值,cl[i][1]记录最小值,lazy做标记

随风的专栏 945

(树链剖分+线段树)POJ - 3237 Tree

前言: 一直听说树链剖分-树链剖分,现在见识一下,,,感觉不是很难0.0 看了一下kuangbin模板基本秒懂 对于点,按重边优先给予每个点一个编号,对于一条重链上的点,编号则是连续的,将所有编号映射到线段树上,即可进行一切区间操作。 对于边的处理,我们将所有边对应到这条边节点更深的那个点上即可。 如果需要的操作只有求和,和单点更新/区间更新,直接用树状数组也是可以的,可能常数...

dijieluan7764的博客 170

【POJ3237】Tree(树链剖分+线段树(基于边权))

题目链接 题目大意: 有T组数据 给你n个点的树 有三种操作: 1.CHANGE i v :将第i条边的值改为v 2.NEGATE a b :将a点到b点路径上的边权取反 3.QUERY a b :查询a点到b点路径上最大的边权值由于有取反操作,我们记录最大值的同时记录下最小值 如果要取反,则将最大最小值取反并交换即可 用线段树维护注意懒惰标记

No Program No Life 621

poj 3237 Tree 树链剖分+线段树

Description You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edges are numbered 1 through N − 1. Each edge is associated with a weight. Then you are to execute a s...

weixin_30278237的博客 135

poj3237Tree 【树链剖分+线段树】

#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <vector> #include <queue> #include <stack> #include <set> #include <map> #include <string> #include <cmath> #inclu

禅境花园 338
上一篇: HDU 5800 - To My Girlfriend-四维DP
下一篇: BZOJ-4034- [HAOI2015]T2-树链剖分+线段树
yuhong_liu
博客等级 码龄18年 97粉丝 731原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值