记众多数据结构的组合题——SDOI2017树点涂色

数据结构——地图填色问题.doc 立即下载

题目描述

Bob有一棵nn 个点的有根树,其中1号点是根节点。Bob在每个点上涂了颜色,并且每个点上的颜色不同。

定义一条路径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜色。

Bob可能会进行这几种操作:

1 x
把点xx 到根节点的路径上所有的点染上一种没有用过的新颜色。

2 x y
求xx 到yy 的路径的权值。

3 x
在以x为根的子树中选择一个点,使得这个点到根节点的路径权值最大,求最大权值。

Bob一共会进行mm 次操作

输入输出格式

输入格式:
第一行两个数n,mn,m 。

接下来n-1n−1 行,每行两个数a,ba,b ,表示aa 与bb 之间有一条边。

接下来mm 行,表示操作,格式见题目描述

输出格式:
每当出现2,3操作,输出一行。

如果是2操作,输出一个数表示路径的权值

如果是3操作,输出一个数表示权值的最大值

输入输出样例

输入样例#1:
5 6
1 2
2 3
3 4
3 5
2 4 5
3 3
1 4
2 4 5
1 5
2 4 5
输出样例#1:
3
4
2
2
说明
n<=1e5,m<=1e5n<=1e5,m<=1e5

时间限制:1s

空间限制:128MB


看到这道题,咦?access?
仔细思考一波,你发现,他可以维护一个当前节点到跟节点的颜色种数,然后利用ans=col(x)+col(y)−2col(lca(x,y))+1ans=col(x)+col(y)−2col(lca(x,y))+1求解,然后你可以利用access和线段树来完成它,但是会有许多坑的地方——

  • 线段树不要写错(比如说把L<=l写成L<=r)
  • 每次修改的子树是原树的子树而不是splay的!
  • depudepu>=depvdepv 不要写成 > !
    下面用代码说明一波:
#include<bits/stdc++.h>
using namespace std;
#define MN 100010
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1 
//fa1 为 袁术  fa2 为 LCT
struct lll{
    int to,ne;
}a[MN*2];
int n,q,x,y,lk[MN],h[MN],up[MN][40],fa2[MN],ch[MN][2],zs[MN],vis[MN],dep[MN],tag[MN*20],
dfn[MN],tot,cnt,opt,mm[MN*20];
void link(int x,int y)
{
    a[++cnt].to=y,a[cnt].ne=h[x],h[x]=cnt;
}
 void dfs(int u)
 {
    lk[u]=++tot,dfn[tot]=u;
    for(int i=1;i<=29;i++) up[u][i]=up[up[u][i-1]][i-1];
    for(int i=h[u];i;i=a[i].ne)
    {
        int v=a[i].to;
        if(!vis[v])
        {
            up[v][0]=u;dep[v]=dep[u]+1;fa2[v]=u;vis[v]=1;dfs(v);
        }
    }
    zs[u]=tot;
 }
 int lca(int u,int v)
 {
    if(dep[u]<dep[v]) swap(u,v);
    for(int i=29;i>=0;i--)
    if(dep[up[u][i]]>=dep[v]) u=up[u][i];// wrong 1st 这里写成了 dep[up[u][i]]>dep[v]
    if(u==v) return u;
    for(int i=29;i>=0;i--)
    if(up[u][i]!=up[v][i]) u=up[u][i],v=up[v][i];
    return up[u][0];
 }
 void pushup(int rt)
 {
    mm[rt]=max(mm[rt<<1],mm[rt<<1|1]);
 }
 void build(int l,int r,int rt)
 {
    if(l==r) {mm[rt]=dep[dfn[l]];return ;}
    int mid=(r+l)>>1;
    build(lson);build(rson);pushup(rt);
 }
 void pushdown(int rt)
 {
    if(tag[rt])
    {
        mm[rt<<1]+=tag[rt],tag[rt<<1]+=tag[rt];
        mm[rt<<1|1]+=tag[rt],tag[rt<<1|1]+=tag[rt];
        tag[rt]=0;
    }
    pushup(rt);
 }
 void update(int L,int R,int l,int r,int rt,int c)
 {
    if(L<=l&&r<=R) {mm[rt]+=c;tag[rt]+=c;return ;}
    int mid=(r+l)>>1;pushdown(rt);
    if(L<=mid) update(L,R,lson,c);
    if(mid<R) update(L,R,rson,c);
    pushup(rt);
 }
 int ask(int pos,int l,int r,int rt)
 {

    if(l==r) {return mm[rt];}
    int mid=(r+l)>>1;pushdown(rt);
    if(pos<=mid) return ask(pos,lson);
    else  return ask(pos,rson);

 }
 int maxx(int L,int R,int l,int r,int rt)
 {
    int ans=-2100000000;
    if(L<=l&&r<=R) return mm[rt];// wrong 2ed 错写为了 L<=r&&r<=R
    int mid=(r+l)>>1;pushdown(rt);
    if(L<=mid) ans=max(ans,maxx(L,R,lson));
    if(mid<R) ans=max(ans,maxx(L,R,rson));
    return ans;
 }
 bool nroot(int x)
 {
    return ch[fa2[x]][1]==x||ch[fa2[x]][0]==x;
 }
 void rotate(int x)
 {
    int old=fa2[x],oldf=fa2[old],which=(ch[old][1]==x),w=ch[x][!which];
    if(nroot(old)) ch[oldf][ch[oldf][1]==old]=x;
    ch[x][!which]=old;ch[old][which]=w;
    if(w) fa2[w]=old;
    fa2[x]=oldf,fa2[old]=x;
 }
 void splay(int x)
 {
    while(nroot(x))
    {
        if(nroot(fa2[x]))
        rotate(((ch[fa2[x]][1]==x)^(ch[fa2[fa2[x]]][1]==fa2[x]))?x:fa2[x]);
        rotate(x);
    }
 }
 int frt(int x)
 {
    while(ch[x][0]) x=ch[x][0];
    return x;
 }
 void access(int x)
 {
    for(int y=0;x;x=fa2[y=x])// wrong 3ed 这里很关键,你修改的是原树的子树所以要findroot一下! 
    {
        int w;
        splay(x);if(ch[x][1]) w=frt(ch[x][1]) ,update(lk[w],zs[w],1,n,1,1);
        ch[x][1]=y;if(y) w=frt(y) ,update(lk[w],zs[w],1,n,1,-1);
    }
 }
 int gsum(int x)
 {
    int ans;
    ans=ask(x,1,n,1);
    return ans;
 }
 void Prt(int l,int r,int rt)
 {
    if(l==r) {printf("%d",mm[rt]);return ;}
    int mid=(l+r)>>1;pushdown(rt);
    Prt(lson);Prt(rson);
 } 
int main()
{
    scanf("%d%d",&n,&q);
    for(int i=1;i<n;i++) scanf("%d%d",&x,&y),link(x,y),link(y,x);
    vis[1]=dep[1]=1;dfs(1);build(1,n,1); 
    //Prt(1,n,1);
    //for(int i=1;i<=n;i++) printf("%d ",dfn[i]);
    //printf("%d",gsum(lk[3]));
    while(q--)
    {
        scanf("%d" ,&opt);
        if(opt==1) scanf("%d",&x),access(x);
        if(opt==2) scanf("%d%d",&x,&y),
        printf("%d\n",(gsum(lk[y])+gsum(lk[x])-2*gsum(lk[lca(x,y)])+1));
        if(opt==3) scanf("%d",&x),printf("%d\n",maxx(lk[x],zs[x],1,n,1));
        //Prt(1,n,1);
    }
    return 0;
}
手把手教你用RMII接口配置以太网PHY芯片(附YT8512实战代码) 本文详细介绍了如何使用RMII接口配置以太网PHY芯片,以国产YT8512为例,提供从硬件设计到软件驱动的全流程实战指南。内容包括RMII接口技术解析、YT8512硬件设计要点、驱动开发实战代码及常见问题排查,帮助开发者快速实现以太网通信功能。 阅读详情

相关推荐

BurpSuit在不同浏览器中配置代理

文章通过分享各大浏览器如何设置代理的知识,帮助初学者快速掌握代理配置相关技能。

北冥同学的成长记录笔记 1万+

【数据结构基础C++】图论应用-用四种颜色对地图上的国家涂色

思想 存储:国家之间只有相邻和不相邻两种关系。把国家看作顶点,用边表示两个国家相邻。考虑到每个国家都要考虑相邻关系,用邻接矩阵存储。 四种色号编号为1,2,3,4;国家序号用 0…n 表示; 用色号循环方式,给国家涂色。 在涂色前,先判断与当前国家相邻的国家的涂色情况:若与之相邻的国家的色号与当前国家色号相同,则用下一个色号涂色; 核心函数:graphColor(int k);isSafe(int k,int color); 掌握这两个函数就可以了! 以这几个省份为例: 抽象成顶点与边的关系: 代

m0_47902113的博客 2925

保姆级教程:手把手教你为STM32F407和W25Q128制作Keil MDK的SPI Flash下载算法(FLM文件)

本文提供了一份详细的教程,指导开发者如何为STM32F407和W25Q128制作Keil MDK的SPI Flash下载算法(FLM文件)。从理解下载算法的核心机制到实现FlashPrg.c的核心操作,再到链接脚本与地址映射实战,手把手教你完成定制化SPI Flash下载算法的开发与优化。

weixin_28716769的博客 408

[SDOI2017]树点涂色

名可铭的题解报告

CM_20030210的博客 656

RV1126B RV1126B-P 瑞芯微 高性能视觉处理器SoC 芯片

它集成了大量算法加速器,如 HDR、3A、LSC、3DNR、2DNR、锐化、去雾、鱼眼校正、伽马校正、特征点检测等。此外,还配备了一款最多8兆像素的 AI-ISP,作为对传统ISP 的补充,以提供卓越的空间去噪性能和增强的图像增强效果。除了先前的高性能多媒体区块外,RV1126B还包含丰富的音频、内存和其他外围接口,如I2C、SPI、PWM等。借助这-特性,来自相机的视频可以以高分辨率进行编码,并存储在本地内存中,同时还能将另-段较低分辨率的视频传输到云存储。

szhorsway的博客 1858

IAR9.4报错之编码方式

IAR9.40编码方式错误导致的报错

qq_36081075的博客 2626

bzoj 4817: [Sdoi2017]树点涂色 link cut tree+线段树+树链剖分

题意Bob有一棵n个点的有根树,其中1号点是根节点。Bob在每个点上涂了颜色,并且每个点上的颜色不同。定义一条路 径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜色。Bob可能会进行这几种操作: 1 x: 把点x到根节点的路径上所有的点染上一种没有用过的新颜色。 2 x y: 求x到y的路径的权值。 3 x y: 在以x为根的子树中选择一个点,使得这个点到根节点的路径权值

beginend 1198

CATIA V5新手必看:从零开始的界面导航与基础操作指南(附常见问题解决)

本文为CATIA V5新手提供全面的界面导航与基础操作指南,涵盖核心工作区解析、文件管理规范、视图操作秘籍及常见问题解决方案。通过详细的步骤说明和实用技巧,帮助用户快速掌握这一工业设计标杆软件,特别适合从SolidWorks、AutoCAD等软件过渡的用户。

b9c0d的博客 527

洛谷P3703 [SDOI2017]树点涂色

题目描述Bob有一棵nn 个点的有根树,其中1号点是根节点。Bob在每个点上涂了颜色,并且每个点上的颜色不同。定义一条路径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜色。Bob可能会进行这几种操作:1 x把点xx 到根节点的路径上所有的点染上一种没有用过的新颜色。2 x y求xx 到yy 的路径的权值。3 x在以x为根的子树中选择一个点,使得这个点到根节点的路径权值最大,求最大权值...

蒟蒻的博客 348

ArcGIS标注(二分式、三分式、条件分类标注、上下标、牵引线、文字格式化…)

ArcGIS中的各种标注方法、可能遇到的问题和细节。

m0_73306837的博客 5267

基于C++和Qt开发IEC104规约主站调试软件(第二章)

本章节主要讲解iec104主站软件界面设计和从站的连接功能以及部分功能代码的展示。

半青年的博客 858

[BZOJ4817][SDOI2017]树点涂色(LCT+线段树+差分)

题目: 我是超链接 题解: 这道题的关键是每一次都是将某一个点到根的路径的点染一种没用过的新颜色 这个操作实际上和lct中的access操作很像,因为都是打通一条到根的路径 那么我们就可以将重边的贡献记为0,轻边的贡献记为1,一棵splay维护一种颜色,每一个点的权记为根到当前点的边的贡献和,那么2操作实际上就是计算val(x)+val(y)-2*val(lca(x,y))+1,3操...

薇小薇 481

华为OD机考双机位C卷 - 评委评分 (Java & Python& JS & C/C++ & GO )

华为OD机考双机位C卷 - 评委评分 (OD上机考试双机位C卷)。提供在线OJ刷题。Java、C++、Python、GO语言、C语言、JavaScript题解,并提供完整思路讲解。

算法大师! 1750

BZOJ4817: [Sdoi2017]树点涂色

Description Bob有一棵n个点的有根树,其中1号点是根节点。Bob在每个点上涂了颜色,并且每个点上的颜色不同。定义一条路 径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜色。Bob可能会进行这几种操作: 1 x: 把点x到根节点的路径上所有的点染上一种没有用过的新颜色。 2 x y: 求x到y的路径的权值。 3 x y: 在以x为根的子树中选择一个点,

wxh010910 823

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

bzoj 4817: [Sdoi2017]树点涂色

lct

LJ__ 884

IEM模型,地表粗糙度模拟

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

告别网络依赖:手把手教你在openEuler欧拉系统上离线搞定Python项目部署(附常见坑点排查)

本文详细介绍了在openEuler欧拉系统上离线部署Python项目的完整流程,包括依赖包精准下载、系统级依赖排查及常见坑点解决方案。针对金融、政务等内网隔离环境,提供从资源库构建到虚拟环境配置的实战指南,帮助开发者高效完成离线部署任务。

weixin_30369041的博客 570

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

loj2001 「SDOI2017」树点涂色

there #include <iostream> #include <cstdio> using namespace std; int n, m, dfn[100005], idx, hea[100005], cnt, uu, vv, siz[100005], fa[100005][19]; int dep[100005], val[400005], dui[1...

dianjiaxian1205的博客 210

深入解析LPC122x系统控制模块:时钟、电源与中断实战指南

在嵌入式系统开发中,微控制器的系统控制模块是决定其性能、功耗和稳定性的核心。该模块通常负责时钟生成与管理、电源控制、复位逻辑及中断处理等基础功能。其原理在于通过可编程寄存器对芯片内部资源进行精细调控,从而实现动态频率调整、低功耗模式切换以及实时响应外部事件。这一技术对于实现高效能、低功耗的嵌入式产品具有重要价值,广泛应用于工业自动化、智能家居和物联网设备等场景。以NXP LPC122x系列ARM Cortex-M0微控制器为例,其系统控制(SYSCON)模块提供了灵活的时钟配置选项,包括内部RC振荡器、外部

agtvo48266的专栏 384

[XJOI]黑白树

题目大意有一棵以11为根的nn个点的树,每个点有黑白两种颜色以及一个权值(一开始都是零)。 有qq个操作,有以下两种: ∙ \bullet\ 选定一个点xx,将所有黑色节点yy的权值加上lca(x,y)lca(x,y) ∙ \bullet\ 将xx号点的颜色反色 在所有操作执行完后,请输出所有点的权值。1≤n,q≤5×1041\le n,q\le5\times10^4题目分析将每个点的编号都

待成熟的葡萄 2219

SDOI2017 树点涂色

传送门 涂色的操作和accessaccessaccess很像啊,如何用LCTLCTLCT维护这个东西呢。 由于每次覆盖的颜色都不同,且是从当前到结点覆盖到根节点。 那么如果把颜色相同的一段维护在一条重链上, 一个点到根要经过多少虚边也就包含多少颜色。 所以用LCTLCTLCT模拟覆盖的过程,用线段树维护即可。 虚变实就是子树减,实变虚就是子树加。 询问1就是val[x]+val[y]−2∗val[...

g21wcr的博客 224

[BZOJ4817][SDOI2017]树点涂色(DFS序+LCA+树剖+LCT)

我一眼以为是裸树剖,但是看完问题就知道不是那么容易了。因为只用树剖不能很好地维护操作33的结果。 首先,按照原树,构建出一个全部都是虚边的LCTLCT,并用树剖维护每个点到根节点的路径权值valval。可以发现,每个点到根节点的路径权值就是每个点到根节点的路径上实链的个数。 我们发现,操作11实际上就是LCTLCT中AccessAccess的操作。在AccessAccess的操作中,如果一条实边

女装的你,如此好看! 467

[POJ3237]树的维护

给你由N个结点组成的树。树的节点被编号为1到N,边被编号为1到N-1。每一条边有一个权值。然后你要在树上执行一系列指令。指令可以是如下三种之一: CHANGE i v:将第i条边的权值改成v。 NEGATE a b:将点a到点b路径上所有边的权值变成其相反数。 QUERY a b:找出点a到点b路径上各边的最大权值。冲着树链剖分来的,结果发现自己太弱了操作二的标记不会打,YY了2个多小时才写完

syxEzre的专栏 1045

NKOI 3691 树上染色

树上涂色                                                                时间限制 : 1000MS   空间限制 : 65536 KB   问题描述   给出一棵有n个节点(编号1到n)的树,开始时每个节点都没有颜色。现在有A和B两种颜色,给第x号节点涂上A颜色需要花费Ax块钱,给x号节点涂上B颜色需要花费Bx块钱。   如果

SuperGate的博客 1260
上一篇: 树上算法总结
下一篇: 对于莫比乌斯相关函数总结
RustSword_RWZ
博客等级 码龄10年 6粉丝 37原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值