poj 3237 树链剖分+线段树

软件崩溃时Visual Studio中看不到有效的调用堆栈,使用Windbg动态调试去分析定位 当在Visual Studio中遇到软件崩溃且无法查看详细调用堆栈时,可以使用Windbg进行动态调试去分析定位问题。 阅读详情

题意就是给你一棵树,每条边上都有权值,有三种操作,把某条边的权值变成v,把点a到点b之间的路径上的边的权值都乘上-1,求a到b的路径上的最大值。

其实这题的线段树要比树链剖分难写,首先,因为有乘-1的操作,所以不光要维护最大值,还要维护最小值,这样在乘-1后,最大值就可以直接根据最小值得到,当然,延迟操作是必须的,其中细节还是蛮多的,需要注意。

好久没敲线段树了,wa了好多发,话说这线段树是有点难度啊,还是自己太弱了。。。

好久没写200+的代码了。。。。

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;

const int maxn = 50010;
int sum1[maxn*4],sum2[maxn*4],add[maxn*4];
struct si{
    int f,t,v,next;
}side[maxn*2];
int head[maxn];
int tid[maxn],ran[maxn],num[maxn],son[maxn];
int top[maxn],fa[maxn],siz[maxn],dep[maxn];
int tim,cnt;
int n;

void dfs1(int u,int father,int d)
{
    dep[u]=d;
    fa[u]=father;
    siz[u]=1;
    for(int i=head[u]; i!=-1; i=side[i].next)
    {
        int v=side[i].t;
        if(v!=father)
        {
            dfs1(v,u,d+1);
            siz[u]+=siz[v];
            if(son[u]==-1||siz[v]>siz[son[u]])
                son[u]=v;
        }
    }
}

void dfs2(int u,int tp)
{
    //cout<<888888<<endl;
    top[u]=tp;
    tid[u]=++tim;
    ran[tid[u]]=u;
    if(son[u]==-1) return;
    dfs2(son[u],tp);
    for(int i=head[u]; i!=-1; i=side[i].next)
    {   //cout<<i<<endl;
        int v=side[i].t;
        //cout<<v<<endl;
        if(v!=son[u]&&v!=fa[u])
            dfs2(v,v);
    }
}

void init(){
    tim=cnt=0;
    memset(head,-1,sizeof(head));
    memset(son,-1,sizeof(son));
}

void addside(int a,int b,int c){
    side[cnt]=(si){a,b,c,head[a]};
    head[a]=cnt++;
    side[cnt]=(si){b,a,c,head[b]};
    head[b]=cnt++;
}

void pushdown(int l,int r,int rt){
    if(add[rt]==-1){
        add[rt<<1]*=-1;
        sum1[rt<<1]=-sum1[rt<<1];
        sum2[rt<<1]=-sum2[rt<<1];
        swap(sum1[rt<<1],sum2[rt<<1]);
        add[rt<<1|1]*=-1;
        sum1[rt<<1|1]=-sum1[rt<<1|1];
        sum2[rt<<1|1]=-sum2[rt<<1|1];
        swap(sum1[rt<<1|1],sum2[rt<<1|1]);

        add[rt]=1;
    }
}

void build(int l,int r,int rt){
    if(l==r){
        sum1[rt]=num[l];
        sum2[rt]=num[l];
        add[rt]=1;
        return ;
    }
    int mid=(l+r)/2;
    build(l,mid,rt<<1);
    build(mid+1,r,rt<<1|1);
    add[rt]=1;
    sum1[rt]=max(sum1[rt<<1],sum1[rt<<1|1]);
    sum2[rt]=min(sum2[rt<<1],sum2[rt<<1|1]);
}

void update(int L,int R,int c,int l,int r,int rt){
    if(l>=L&&r<=R){
        sum1[rt]=sum2[rt]=c;
        add[rt]=1;
        return;
    }
    pushdown(l,r,rt);
    int mid=(l+r)/2;
    if(mid>=L) update(L,R,c,l,mid,rt<<1);
    if(mid+1<=R) update(L,R,c,mid+1,r,rt<<1|1);
    sum1[rt]=max(sum1[rt<<1],sum1[rt<<1|1]);
    sum2[rt]=min(sum2[rt<<1],sum2[rt<<1|1]);
}

void change(int a,int b){
    int f=side[a*2-1].f,t=side[2*a-1].t;
    if(dep[f]<dep[t]) swap(f,t);
    update(tid[f],tid[f],b,2,n,1);
}

void upda(int L,int R,int l,int r,int rt){
    if(l>=L&&r<=R){
        add[rt]*=-1;
        sum1[rt]=-sum1[rt];
        sum2[rt]=-sum2[rt];
        swap(sum1[rt],sum2[rt]);
        return ;
    }
    pushdown(l,r,rt);
    int mid=(l+r)/2;
    if(mid>=L) upda(L,R,l,mid,rt<<1);
    if(mid+1<=R) upda(L,R,mid+1,r,rt<<1|1);
    sum1[rt]=max(sum1[rt<<1],sum1[rt<<1|1]);
    sum2[rt]=min(sum2[rt<<1],sum2[rt<<1|1]);
}

void Negate(int a,int b){
    while(top[a]!=top[b]){
        if(dep[top[a]]<dep[top[b]]) swap(a,b);
        upda(tid[top[a]],tid[a],2,n,1);
        a=fa[top[a]];
    }
    if(dep[a]<dep[b]) swap(a,b);
    if(a!=b) upda(tid[b]+1,tid[a],2,n,1);
}

int query(int L,int R,int l,int r,int rt){
    if(l>=L&&r<=R){
        return sum1[rt];
    }
    pushdown(l,r,rt);
    int ans=-1e9;
    int mid=(l+r)/2;
    if(mid>=L) ans=max(ans,query(L,R,l,mid,rt<<1));
    if(mid+1<=R) ans=max(ans,query(L,R,mid+1,r,rt<<1|1));
    return ans;
}

void Query(int a,int b){
    int ans=-1e9;
    while(top[a]!=top[b]){
        if(dep[top[a]]<dep[top[b]]) swap(a,b);
        ans=max(ans,query(tid[top[a]],tid[a],2,n,1));
        a=fa[top[a]];
    }
    if(dep[a]<dep[b]) swap(a,b);
    if(a!=b) ans=max(ans,query(tid[b]+1,tid[a],2,n,1));
    printf("%d\n",ans);
}

int main()
{
    //freopen("in.txt","r",stdin);
    int cas;
    cin>>cas;
    while(cas--){
        init();
        cin>>n;
        int a,b,c;
        for(int i=0;i<n-1;i++){
            scanf("%d %d %d",&a,&b,&c);
            addside(a,b,c);
        }
        dfs1(1,1,1);
        dfs2(1,1);
        //for(int i=1;i<=3;i++) cout<<tid[i]<<' ';cout<<endl;
        for(int i=0;i<cnt;i+=2){
            int f=side[i].f,t=side[i].t,v=side[i].v;
            if(dep[f]>dep[t]) num[tid[f]]=v;
            else num[tid[t]]=v;
        }
        build(2,n,1);
        char s[20];
        while(1){
            scanf("%s",s);
            if(s[0]=='D') break;
            scanf("%d %d",&a,&b);
            if(s[0]=='C') change(a,b);
            if(s[0]=='Q') Query(a,b);
            if(s[0]=='N') Negate(a,b);
        }
    }
    return 0;
}


RHCA III之路---EX436-1 由于ha这门课有大量命令需要在3个节点上同步执行.如果执行history会出现前面数字,复制多行会有些麻烦.lab环境是nodea,nodeb,nodec 考试环境是node1,node2,node3。就可以快速将历史命令实现可多行复制,当然也可以用awk进行分割,个人喜好随意。技巧只能加快答题速度,对考试得分帮助不大。确认3个红框内容一致,且没报错即可。再执行一个histrory。3个node节点上运行。这样就能1次复制3行。 阅读详情

相关推荐

unity制作交互视频/互动视频

unity制作交互视频/互动视频 思路 1.先让unity播放视频 2. 视频播放结束后,视频暂停,按钮出现 3.按钮跳转下一个视频 视频播放 先创建UI-Raw Iamge 在Raw Iamge 挂载组件 Video Player 接着挂载视频播放的脚本 using UnityEngine; using UnityEngine.UI; using UnityEngine.Video; publi...

weixin_45588911的博客 8423

树链剖分

原文地址:树链剖分作者:starszys  “在一棵树上进行路径的修改、求极值、求和”乍一看只要线段树就能轻松解决,实际上,仅凭线段树是不能搞定它的。我们需要用到一种貌似高级的复杂算法——树链剖分。     树链,就是树上的路径。剖分,就是把路径分类为重链和轻链。     记siz[v]表示以v为根的子树的节点数,dep[v]表示v的深度(根深度为1),top[v]表

Lazier’s blog 771

`全网最细!! 入门必看Git教程链接:https://gitee.com/all-about-git`

全网 Git 入门教程 gitee.com。如果显示The requested URL returned error: 403错误,那就表示没有和window本地建立token令牌

qq_37855368的博客 3747

HDU 3966 (树链剖分+线段树)

ProblemAragorn's Story (HDU 3966) 题目大意   给定一颗树,有点权。   要求支持两种操作,将一条路径上的所有点权值增加或减少ai,询问某点的权值。 解题分析   树链剖分模板题。   实质上树链剖分进行了点对点的一次映射,保证了重链上的点在线段树上的位置是连续的。   树链剖分的两个性质(转):     性质1:如果(v,u)为轻边,...

aekijekzn484879763的博客 190

某音播放量查询,播放量接口研究,最新版本抓包,修改SO文件绕过SSL

本教程适用于某音27.8,64位版本,32为版本及某音旁侧版本修改方法大同小异,部分旁侧版本修改之后模拟器可能无法抓包,真机测试均可正常抓包,此方法修改后绝大部分包可以正常抓取,但部分包无法抓取,例如验证码,内置浏览器功能,如需抓取此类包可通过 Postern + Charles 实现。

byalipus的博客 1万+

[前沿技术] AMD FSR 1.0源码解析:EASU算法实现细节与优化策略

本文深入解析了AMD FSR 1.0技术的核心——EASU(边缘自适应空间升频)算法。通过剖析其源码,详细阐述了EASU如何利用12-tap采样窗口、基于Lanczos滤波器的多项式近似以及自适应的边缘检测机制,在无需AI模型的情况下实现高质量图像放大。文章重点揭示了其极致的GPU优化策略,包括寄存器利用、采样优化和避免动态分支,为理解高性能图形算法提供了绝佳范例。

docker7nomad的博客 540

hdu 3966 (树链剖分+线段树)

题意:给出一棵树,每个节点有一些敌人,有三种操作,I:x,y,路径上的所有点的人数+w。D:x,y,路径上的所有点的人数-w。Q:节点x的人数。 思路:如果是线性的线段树可以做,所以要树链剖分,剖分后的每条链是线性的,更改区间时用找公共祖先的方式,将两点找到同一条链上,同一条链上的两点间可以直接线段树更改。 #pragma comment(linke

菜鸟起航的专栏 1646

别再手动更新Excel了!用Jira看板管理你的个人项目(附保姆级配置流程)

本文详细介绍了如何利用Jira看板替代Excel进行个人项目管理,提供从注册到配置的保姆级教程。通过极简看板模式、自动化规则和数据分析功能,帮助用户实现任务可视化、协作高效化和提醒自动化,大幅提升个人工作效率。特别适合需要管理复杂个人项目的用户。

weixin_42699679的博客 228

树链剖分+线段树 poj3237 Tree

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

qwb的博客 856

C++幂运算全解析:std::pow()函数详解与实战指南

本文详细介绍了C++标准库中的std::pow()函数,包括其基本用法、数学定义和多种重载形式。重点分析了该函数在科学计算、图形处理等领域的实际应用,并提供了性能优化方案如快速幂算法和预计算表。文章还探讨了精度控制、错误处理等关键问题,最后通过一个完整计算器实现展示了综合应用。std::pow()作为基础数学函数,合理使用能显著提升计算效率和代码可靠性。

专注现代C++实战,从核心语法到高性能编程,助力开发者深入掌握系统级编程精髓。 340

轨道平面系与轨道姿态系

文章摘要: 轨道平面系与轨道姿态系是航天任务中两个核心坐标系。轨道平面系(惯性系)以地心为原点,Z轴沿轨道角动量方向,用于轨道确定和机动规划;轨道姿态系(如LVLH系)以航天器质心为原点,Z轴指向地心,用于姿态控制和对地观测。两者通过旋转矩阵相互转换:轨道平面系基于轨道根数构建,保持静态;而LVLH系随轨道运动连续旋转。前者适用于全局轨道分析,后者支撑局部任务执行。理解二者的定义差异(原点、基准轴、惯性属性)及数学转换关系,对航天器姿态轨道控制系统的设计与操作至关重要。

ScilogyHunter的博客 88

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

C# WinForms 多语种切换实现:打造国际化应用程序

合理实现多语种切换功能可以显著提升应用程序的国际化水平。模块化设计:将本地化逻辑模块化,便于管理和维护。异常处理:始终捕获和处理可能的异常,确保程序的健壮性。资源管理:合理管理资源文件,避免重复和遗漏。测试:在不同语言环境下进行全面测试,确保所有字符串都能正确显示。文档和注释:为关键代码添加详细的文档和注释,便于后续维护。

墨夶的博客 1691

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

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

jre9下载 jdk9

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

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

题解:更改把路径上的边值都变为负值一看就是树链剖分,接着我们用点连着深度比较深的边的值设为边的值那么我们查询的时候当到达最近公共祖先的时候最近公共祖先的点的编号注意加一,接着就是线段树的更新用1和0表示区间变为负数或者不变为负数即可,最后要记录一下边队应的编号即可 #include #include #include #include using namespace std; #define l

Soul 458

visio安装包

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

「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

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

POJ3237 (树链剖分+线段树)

Problem Tree (POJ3237) 题目大意   给定一颗树,有边权。   要求支持三种操作:     操作一:更改某条边的权值。     操作二:将某条路径上的边权取反。     操作三:询问某条路径上的最大权值。 解题分析   树链剖分+线段树。练手题。 参考程序 1 #include <cstdio> 2 #include...

aekijekzn484879763的博客 145

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

题目链接:我是链接! 题意:在一棵树上,点和点之间的路径有边权,有三种操作 CHANGE把第i条边的权值改为a,NEGATE把第a个点到第b个点的边的权值全部取相反数,QUERY求第a个点到第b个点的最大边权。 分析:树链剖分的模板题了,之前写的用树状数组维护就可以了,这次稍微复杂一点用线段树+懒操作来维护。但是考虑到需要加lazy标记,所以除了区间最大值以外还需要维护一个区间最小值。然后每次...

可以说非常弱鸡 528

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

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

MissZhou要努力 1628

POJ3237 Tree 树链剖分 线段树

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

weixin_30408165的博客 123

poj 3237(树链剖分+线段树)

题意:给一棵树,三种操作。将第i条边的权值改为v,将a到b的路径上的边的权值全部取反,求a到b路径上边的权值的最大值。 思路:明显的树链剖分,加上线段树的操作。因为有取反的操作所以每个区间要记录最大值和最小值。查询两点间的路径时,用求公共祖先的方式去求。 #include #include #include const int N=101000; const

菜鸟起航的专栏 1109

cogs 1583. [POJ 3237] 树的维护 树链剖分套线段树

1583. [POJ 3237] 树的维护 ★★★★ 输入文件:maintaintree.in 输出文件:maintaintree.out简单对比时间限制:5 s 内存限制:128 MB 【题目描述】 给你由N个结点组成的树。树的节点被编号为1到N,边被编号为1到N-1。每一条边有一个权值。然后你要在树上执行一系列指令。指令可以是如下三种之一: CHANGE i...

weixin_30451709的博客 143

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

题意: http://poj.org/problem?id=3237 给一棵树,操作三种  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 

缺氧 704

poj 3237(树链剖分+线段树)

题意:给一棵树,三种操作。将第i条边的权值改为v,将a到b的路径上的边的权值全部取反,求a到b路径上边的权值的最大值。 思路:明显的树链剖分,加上线段树的操作。因为有取反的操作所以每个区间要记录最大值和最小值。查询两点间的路径时,用求公共祖先的方式去求。 #include<iostream> #include<stdio.h> #inc...

weixin_30847939的博客 143

poj 3237 Tree 树链剖分 线段树

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

kkkkahlua的博客 324

POJ 3237 树链剖分+线段树维护

和QTREE1类似,增加了NEGATE操作。 记几个踩到的坑: 1. 维护数据量为n(假设n为2的幂)的线段树的大小为2*n-1,此题线段树的数组大小应为2^15-1,在写的时候写成1&amp;lt;&amp;lt;15-1,C++的&amp;lt;&amp;lt;的优先级小于-,实际开出来是2^14。 2. 这样写之后没有数组越界的异常,而是不断的WA。全局变量的内存分配在堆区,虽然访问的范围超过了数组的大小,但是在...

Lonvon_的博客 394
上一篇: poj 3237 树链剖分
下一篇: poj 3419 Difference Is Beautiful 离线线段树
ACMer_浩
博客等级 码龄12年 0粉丝 26原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值