hdu 5756:Boss Bo

2023-11-15

题目链接如下:

Problem - 5756

先用dfs确定每个节点的序号编号,并且可以获得每个节点可以包括的子树节点区间范围,再用线段树建立一棵树。

在第一次建立的时候我们记录每个节点的深度,然后再进行一次dfs,这次dfs用来更新以不同节点为根时,距离的维护,利用子树距离减1,非子树距离加1的方法进行更新距离和,最大距离和最小距离。同时不断建立树来打上懒标记,这里打标记的顺序也是dfs的,意味着我们query的时候要进行标记的计算,因为子树并没有更新根节点打上的懒标记。

最后利用补集的方式求出good node 到其余节点的距离。

参考:

hdu 5756(主席树)_top628LJ的博客-CSDN博客

代码如下所示:

#include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>
#include <cstdlib>
using namespace std;
#define inf 0x3f3f3f3f
#define MP make_pair
#define mid ((l+r)>>1)
#define pii pair<int,int>
const int MAXN = 100020;
const int MAXM = 500020;
int n,q;
//  fst记录一个节点连接的第一条边  vv记录连接到的节点 nxt记录下一条边索引
//  fst大小和节点数目一致
int fst[MAXN], vv[MAXM], nxt[MAXM], e;
//  st记录节点dfs序的左端点 ed代表右端点 dep表示节点深度 lab表示左端点对应的节点号
int st[MAXN],ed[MAXN],dep[MAXN],lab[MAXN],dc;
//  sum mx mi代表和 最大值 最小值 add表示懒标记 ch代表子树位置
int sum[MAXN*50],mx[MAXN*50],mi[MAXN*50],add[MAXN*50],ch[MAXN*50][2];
int rt[MAXN], tot;
pii a[MAXN*5];

void init(){
    memset(fst, -1, sizeof(fst));
    e=0;
}

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

void dfs(int u, int p, int d){
    dep[u]=d;
    st[u]=++dc;
    lab[dc]=u;
    for (int i = fst[u]; ~i ; i = nxt[i]) {
        int v = vv[i];
        if (v == p) continue;
        dfs(v,u,d+1);
    }
    ed[u]=dc;
}

void push_up(int l,int r,int rt){
    int l_rt=ch[rt][0], r_rt=ch[rt][1];
    sum[rt]=sum[l_rt]+sum[r_rt]+(r-l+1)*add[rt];
    mx[rt]=max(mx[l_rt], mx[r_rt])+add[rt];
    mi[rt]=min(mi[l_rt], mi[r_rt])+add[rt];
}

int build(int l,int r){
    int k=++tot;
    if (l==r){
        sum[k]=mx[k]=mi[k]=dep[lab[l]]-1;
        ch[k][0]=ch[k][1]=add[k]=0;
        return k;
    }
    sum[k]=mx[k]=mi[k]=add[k]=0;
    ch[k][0]=build(l,mid);
    ch[k][1]=build(mid+1, r);
    push_up(l,r,k);
    return k;
}

int update(int ul, int ur, int val,int l,int r,int rt){
    int k=++tot;
    sum[k]=sum[rt], mx[k]=mx[rt], mi[k]=mi[rt], add[k]=add[rt];
    ch[k][0]=ch[rt][0], ch[k][1]=ch[rt][1];
    if (ul==l && ur==r){
        sum[k]+=(r-l+1)*val;
        mx[k]+=val;
        mi[k]+=val;
        add[k]+=val;
        return k;
    }
    if (ur<=mid) {
        ch[k][0]=update(ul,ur,val,l,mid,ch[rt][0]);
    } else if (ul>mid) {
        ch[k][1]=update(ul,ur,val,mid+1,r,ch[rt][1]);
    } else {
        ch[k][0]=update(ul,mid,val,l,mid,ch[rt][0]);
        ch[k][1]=update(mid+1,ur,val,mid+1,r,ch[rt][1]);
    }
    push_up(l,r,k);
    return k;
}

void dfs1(int u,int p){
    for (int i = fst[u]; ~i ; i=nxt[i]) {
        int v=vv[i];
        if (v==p) continue;
        rt[v]= update(st[v],ed[v],-1,1,n,rt[u]);
        if (st[v]>1){
            rt[v]= update(1,st[v]-1,1,1,n,rt[v]);
        }
        if (ed[v]<n){
            rt[v]= update(ed[v]+1,n,1,1,n,rt[v]);
        }
        dfs1(v,u);
    }
}

int query(int ul,int ur,int t,int l,int r,int rt){
    if (ul==l && ur==r){
        if(t == 1) return sum[rt];
        else if(t == 2) return mi[rt];
        else return mx[rt];
    }
    if (ur<=mid){
        int ret = query(ul,ur,t,l,mid,ch[rt][0]);
        if (t==1) ret+=(ur-ul+1)*add[rt];
        else ret+=add[rt];
        return ret;
    }else if (ul>mid) {
        int ret = query(ul,ur,t,mid+1,r,ch[rt][1]);
        if (t==1) ret+=(ur-ul+1)*add[rt];
        else ret+=add[rt];
        return ret;
    }else {
        int ret1 = query(ul,mid,t,l,mid,ch[rt][0]);
        int ret2 = query(mid+1,ur,t,mid+1,r,ch[rt][1]);
        if (t==1) return ret1+ret2+(ur-ul+1)*add[rt];
        else if (t==2) return min(ret1, ret2)+add[rt];
        else return max(ret1,ret2)+add[rt];
    }
}

int main(){
    int u,v;
    while (~scanf("%d %d", &n, &q)){
        init();
        for (int i = 1; i < n; ++i) {
            scanf("%d %d", &u, &v);
            adde(u,v);
            adde(v,u);
        }
        dc=0;
        dfs(1,-1,1);
        tot=0;
        rt[1]= build(1,n);
        dfs1(1,-1);
        int K,P,T,ans=0,x;
        while (q--){
            scanf("%d %d %d",&K,&P,&T);
//            cout << "K, P, T:" << K << "," << P << "," << T <<endl;
            P=(P+ans)%n+1;
            bool ok= false;
            for (int i = 1; i <= K; ++i) {
                scanf("%d",&x);
                a[i]=MP(st[x],ed[x]);
//                cout<<"i:"<<i<<",x:"<<x<<",[st,ed]:"<<"["<<st[x]<<","<<ed[x]<<"]"<<endl;
                if (x==1){
                    ok=true;
                }
            }
            if (ok){
                puts("-1"); ans = 0;
                continue;
            }
            sort(a+1,a+1+K);
            a[++K]=MP(n+1,n+1);
            if (T==1) ans=0;
            else if (T==2) ans=inf;
            else ans=-inf;
            int pre=1;

            for (int i = 1; i <= K; ++i) {
                if (pre<a[i].first){
                    int res = query(pre,a[i].first-1, T,1,n,rt[P]);
//                    cout<<"In for i:"<<i<<",[st,ed]:"<<"["<<a[i].first<<","<<a[i].second<<"]"<<endl;
//                    cout << "res:"<<res<<endl;
                    if (T==1) {
                        ans+= res;
                    }else if (T==2) {
                        ans= min(ans,res);
                    }else {
                        ans= max(ans,res);
                    }
                }
                pre=max(pre,a[i].second+1);
            }
            printf("%d\n", ans);
        }
    }
    return 0;
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

hdu 5756:Boss Bo 的相关文章

  • 蓝桥杯精选赛题算法系列——迷宫——DFS

    已收录此专栏 今天我们会全面学习 DFS 的相关知识 包括理论 模板 真题等 深度优先搜索 DFS Depth First Search 和宽度优先搜索 BFS Breadth First Search 或称为广度优先搜索 是基本的暴力技术

随机推荐

  • Apache Flink不止于计算,数仓架构或兴起新一轮变革

    2021 年初 在 InfoQ 编辑部策划的全年技术趋势展望中 我们提到大数据领域将加速拥抱 融合 或 一体化 演进的新方向 本质是为了降低大数据分析的技术复杂度和成本 同时满足对性能和易用性的更高要求 如今 我们看到流行的流处理引擎 Ap
  • electron globalShortcut 快捷键与系统全局快捷键冲突

    用 electron 开发自己的接口测试工具 Post Tools 在设置了 globalShortcut 快捷键后 发现应用中的快捷键与系统全局快捷键冲突了 导致系统快捷键不可正常使用 快捷键配置 export function init
  • GTest学习笔记(七)

    参考博客 Advanced googletest Topics GoogleTest 前言 参数化测试允许对代码进行多种输入的测试 而不需要复制很多相同的代码 本文主要介绍GTest的参数化测试的适用环境 编写方式以及参数化的抽象测试 1
  • 架构设计之道【精】

    一 本质 在了解架构本质之前先了解下架构的定义 百度百科对架构的定义 架构又名软件架构 是有关软件整体结构与组件的抽象描述 用于指导大型软件系统各个方面的设计 从定义中我们提炼出几个关键字 组件 结构 关系 组件 也可以称为软件元素或者是架
  • vscode 扩展开发从入门到颈椎病康复

    笔者从业以来 各路插件开发无算 而 vscode 把插件开发体验做到了极致 其开发体验 如沐春风 如丝般顺滑 经常写完了还想删掉再写一遍 vscode 扩展的内置脚手架细心且精致 一键生成后即可运行 vscode 库类型完美 因此开发者可以
  • Sentinel + Gateway网关动态限流

    Sentinel 控制台 0 概述 Sentinel 控制台是流量控制 熔断降级规则统一配置和管理的入口 它为用户提供了机器自发现 簇点链路自发现 监控 规则配置等功能 在 Sentinel 控制台上 我们可以配置规则并实时查看流量控制效果
  • python爬虫要用到的库_Python写爬虫都用到什么库

    Python爬虫 全称Python网络爬虫 是一种按照一定的规则 自动地抓取万维网信息的程序或脚本 主要用于抓取证券交易数据 天气数据 网站用户数据和图片数据等 Python为支持网络爬虫正常功能实现 内置了大量的库 主要有几种类型 下面本
  • 音频处理-2 WAV格式

    后续要将流量中的音频数据转为WAV格式文件 所以本节重点说下WAV格式 WAV文件是在PC机平台上很常见的 最经典的多媒体音频文件 最早于1991年8月出现在Windows 3 1操作系统上 文件扩展名为WAV 是WaveFom的简写 也称
  • MarkDown超级教程 Obsidian版_11.4

    date 2021 11 3 18 01 aliases Markdown教程 MD教程 tags Markdown 什么是 Markdown Markdown 是一款轻量级标记语言 不同于HTML Hypertext Markup Lan
  • 修改notebook的默认路径_Anaconda3修改jupyter_notebook打开的默认路径

    1 windows下 找到jupyter notebook配置文件jupyter notebook config py 默认安装在 C Users Administrator jupyter jupyter notebook config
  • GB28181协议EasyGBS国标视频云平台无法正常启动的排查步骤与解决方法

    EasyGBS国标视频云服务是基于国标GB T28181协议的视频能力平台 可实现的视频功能包括 实时监控直播 录像 检索与回看 语音对讲 云存储 告警 平台级联等功能 平台部署简单 可拓展性强 支持将接入的视频流进行全终端 全平台分发 分
  • upload-labs

    pass 01 先发一个后缀名为PHP的文件 发现不能上传 然后禁用js 说明 js就是所谓的客户端脚本语言 是一种在互联网浏览器 浏览器也称为Web客户端 因为它连接到Web服务器上 以下载页面 内部运行的计算机编程语言 普通网页内都会插
  • React新出来两个钩子函数是什么?和删掉的will系列有什么区别?

    React新出来两个钩子函数是什么 和删掉的will系列有什么区别 react16废弃的生命周期有3个will componentWillMount componentWillReceiveProps componentWillUpdate
  • SolidWorks二次开发语法技巧及基础

    语法 变量 HRESULT 接口返回值 用于异常调用时判断 本质 typedef LONG HRESULT 32位 S OK S FALSE OLECHAR 特定平台上表示文本数据 win32内 定义为 wchar t 16 或32 位 c
  • 正大国际:做期货交易的方法

    以多为例 空则反之 1 顺势交易 这话估计听的耳朵都起茧子了 但是还是要强调 顺势 顺势 不要抄底 不要摸顶 2 势的判断 做明晃晃的趋势 一眼就看出在上涨的 你就是找个小学生 老太太等完全不懂交易的 让他看走势图 他都知道在上涨 这就是明
  • 区块链知识转载博文1: 共识算法之争(PBFT,Raft,PoW,PoS,DPoS,Ripple)

    注 这是本人读到的关于共识算法最全和最好的分享博文 系统的介绍了拜占庭容错技术以及共识算法的原理和常用共识算法 原文链接请见后 目录 一 拜占庭容错技术 Byzantine Fault Tolerance BFT 二 PBFT Practi
  • 智慧“昆明”在路上 未来充满精彩

    智慧城市是运用物联网 云计算 大数据 移动互联网 空间地理信息集成等新一代信息技术 促进城市规划 建设 管理和服务智慧化的新理念和新模式 近年来 昆明市全面加快智慧城市建设 力争通过三年的努力 打造区域信息辐射中心的核心区 生态 融合发展的
  • Spring Boot系列四 Spring @Value 属性注入使用总结一

    Value注入 不通过配置文件的注入属性的情况 通过 Value将外部的值动态注入到Bean中 使用的情况有 注入普通字符串 注入操作系统属性 注入表达式结果 注入其他Bean属性 注入beanInject对象的属性another 注入文件
  • C语言if选择练习题

    C语言实现输出对应成绩的等级 include
  • hdu 5756:Boss Bo

    题目链接如下 Problem 5756 先用dfs确定每个节点的序号编号 并且可以获得每个节点可以包括的子树节点区间范围 再用线段树建立一棵树 在第一次建立的时候我们记录每个节点的深度 然后再进行一次dfs 这次dfs用来更新以不同节点为根