[树链剖分][SDOI 2011]染色,Housewife Wind

文章目录

  • T1:Housewife Wind
    • 题目
    • 题解
    • code
  • T2:染色
    • 题目
    • 题解
    • code

今天选择写这篇博客主要是为了告诉大家一个道理,数组比vectorvectorvector快太多了,我这两道题第一次都因为vectorvectorvectorTTT到飞起
在这里插入图片描述

T1:Housewife Wind

题目

After their royal wedding, Jiajia and Wind hid away in XX Village, to enjoy their ordinary happy life. People in XX Village lived in beautiful huts. There are some pairs of huts connected by bidirectional roads. We say that huts in the same pair directly connected. XX Village is so special that we can reach any other huts starting from an arbitrary hut. If each road cannot be walked along twice, then the route between every pair is unique.

Since Jiajia earned enough money, Wind became a housewife. Their children loved to go to other kids, then make a simple call to Wind: ‘Mummy, take me home!’

At different times, the time needed to walk along a road may be different. For example, Wind takes 5 minutes on a road normally, but may take 10 minutes if there is a lovely little dog to play with, or take 3 minutes if there is some unknown strange smell surrounding the road.

Wind loves her children, so she would like to tell her children the exact time she will spend on the roads. Can you help her?
Input
The first line contains three integers n, q, s. There are n huts in XX Village, q messages to process, and Wind is currently in hut s. n < 100001 , q < 100001.

The following n-1 lines each contains three integers a, b and w. That means there is a road directly connecting hut a and b, time required is w. 1<=w<= 10000.

The following q lines each is one of the following two types:

Message A: 0 u
A kid in hut u calls Wind. She should go to hut u from her current position.
Message B: 1 i w
The time required for i-th road is changed to w. Note that the time change will not happen when Wind is on her way. The changed can only happen when Wind is staying somewhere, waiting to take the next kid.
Output
For each message A, print an integer X, the time required to take the next child.
Sample Input
3 3 1
1 2 1
2 3 2
0 2
1 2 3
0 3
Sample Output
1
3

题解

其实这道题就是一个边权模板题,这篇博客的重点是后面的染色
其次这道题我被卡了vectorvectorvector所以来记录一下数组版怎么写罢了vector版边权模板
我觉得没有什么讲的必要,直接上就行了,如果刚刚踏入门的话,→移步入门树链剖分
在这里插入图片描述

code

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
#define maxn 100005
struct noded {int u, v;int w;noded () {}noded ( int U, int V, int W ) {u = U;v = V;w = W;}
}tmp[maxn];
struct EDGE {int to, next;
}edge[maxn << 1];
int cnt = 1, n, q, s;
int f[maxn], son[maxn], dep[maxn], Size[maxn];
int id[maxn], Top[maxn];
int tree[maxn << 2];
int head[maxn];void update ( int t, int l, int r, int idx, int val ) {if ( l == r ) {tree[t] = val;return;}int mid = ( l + r ) >> 1;if ( idx <= mid )update ( t << 1, l, mid, idx, val );elseupdate ( t << 1 | 1, mid + 1, r, idx, val );tree[t] = tree[t << 1] + tree[t << 1 | 1];
}int query ( int t, int l, int r, int L, int R ) {if ( L <= l && r <= R )return tree[t];int mid = ( l + r ) >> 1;int ans = 0;if ( L <= mid )ans += query ( t << 1, l, mid, L, R );if ( mid < R )ans += query ( t << 1 | 1, mid + 1, r, L, R );return ans;
}void addedge ( int u, int v ) {edge[cnt].to = v;edge[cnt].next = head[u];head[u] = cnt ++;
}void dfs1 ( int u, int fa, int depth ) {f[u] = fa;dep[u] = depth;Size[u] = 1;for ( int i = head[u];i != -1;i = edge[i].next ) {int v = edge[i].to;if ( v == fa )continue;dfs1 ( v, u, depth + 1 );Size[u] += Size[v];if ( Size[v] > Size[son[u]] || ! son[u] )son[u] = v;}
}void dfs2 ( int u, int t ) {Top[u] = t;id[u] = ++ cnt;if ( ! son[u] )return;dfs2 ( son[u], t );for ( int i = head[u];i != -1;i = edge[i].next ) {int v = edge[i].to;if ( v != son[u] && v != f[u] )dfs2 ( v, v );}
}int solve ( int x, int y ) {int ans = 0;int fx = Top[x], fy = Top[y];while ( fx != fy ) {if ( dep[fx] > dep[fy] ) {ans += query ( 1, 1, n, id[fx], id[x] );x = f[fx];fx = Top[x];}else {ans += query ( 1, 1, n, id[fy], id[y] );y = f[fy];fy = Top[y];}}if ( id[x] < id[y] )ans += query ( 1, 1, n, id[x] + 1, id[y] );elseans += query ( 1, 1, n, id[y] + 1, id[x] );return ans;
}int main() {scanf ( "%d %d %d", &n, &q, &s );memset ( head, -1, sizeof ( head ) );for ( int i = 1;i < n;i ++ ) {scanf ( "%d %d %d", &tmp[i].u, &tmp[i].v, &tmp[i].w );addedge ( tmp[i].u, tmp[i].v );addedge ( tmp[i].v, tmp[i].u );}cnt = 0;//建边的时候不小心用到了,一定要清零 dfs1 ( 1, 0, 1 );dfs2 ( 1, 0 );for ( int i = 1;i < n;i ++ ) {if ( dep[tmp[i].u] > dep[tmp[i].v] )swap ( tmp[i].u, tmp[i].v );update ( 1, 1, cnt, id[tmp[i].v], tmp[i].w );}int opt, x, w;for ( int i = 1;i <= q;i ++ ) {scanf ( "%d %d", &opt, &x );if ( opt ) {scanf ( "%d", &w );update ( 1, 1, n, id[tmp[x].v], w );}else {printf ( "%d\n", solve ( s, x ) );s = x;//注意接完孩子后,mom就待在了那里}}return 0;
}

T2:染色

题目

给定一棵有n个节点的无根树和m个操作,操作有2类:
1、将节点a到节点b路径上所有点都染成颜色c;
2、询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段),
如“112221”由3段组成:“11”、“222”和“1”。
请你写一个程序依次完成这m个操作。
Input
第一行包含2个整数n和m,分别表示节点数和操作数;
第二行包含n个正整数表示n个节点的初始颜色
下面 行每行包含两个整数x和y,表示x和y之间有一条无向边。
下面 行每行描述一个操作:
“C a b c”表示这是一个染色操作,把节点a到节点b路径上所有点(包括a和b)都染成颜色c;
“Q a b”表示这是一个询问操作,询问节点a到节点b(包括a和b)路径上的颜色段数量。
Output
对于每个询问操作,输出一行答案。

Sample Input
6 5
2 2 1 2 1 1
1 2
1 3
2 4
2 5
2 6
Q 3 5
C 2 1 1
Q 3 5
C 5 1 2
Q 3 5
Sample Output
3
1
2
Hint
N<=105N<=10^5N<=105,操作数M<=105M<=10^5M<=105,所有的颜色C为整数且在[0, 10^9]之间。

题解

其实这道题说难也不难,简单也不简单
在这里插入图片描述


首先这个是点权题,降低了一定难度,其次改颜色的操作也是模板,我们直接进入如何统计颜色段数
在这里插入图片描述
可以知道当两个区间进行合并的时候,交接处如果颜色相同的话,就并成了一段颜色,所以我们就要在线段树时判断,可以返回一个结构体带三个参数最左边的颜色最右边的颜色和颜色的段数

然后就是树链剖分的时候我们要记录上一次的左右颜色,分别于两个点的左右进行合并判断,这里主要是考察码力,可以直接看solvesolvesolve函数,我稍微改变了一下写法
在这里插入图片描述

code

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
#define maxn 100005
#define INF 0x7f7f7f7f
struct node {//用vector太慢了 int next, v;
}edge[maxn << 1];
struct noded {int lcolor, rcolor, sum;
}tree[maxn << 2];
int head[maxn], tag[maxn << 2];
int cnt;
int f[maxn], son[maxn], dep[maxn], Size[maxn];
int id[maxn], top[maxn];
int color[maxn];void addedge ( int x, int y ) {cnt ++;edge[cnt].next = head[x];edge[cnt].v = y;head[x] = cnt;
}void pushdown ( int t ) {//不用lazy标记要超时 if ( ! tag[t] )return;tree[t << 1].lcolor = tree[t << 1].rcolor = tree[t << 1 | 1].lcolor = tree[t << 1 | 1].rcolor = tag[t];tag[t << 1] = tag[t << 1 | 1] = tag[t];tag[t] = 0;tree[t].sum = tree[t << 1].sum = tree[t << 1 | 1].sum = 1;
}void update ( int t, int l, int r, int L, int R, int v ) {if ( L <= l && r <= R ) {tree[t].lcolor = tree[t].rcolor = tag[t] = v;tree[t].sum = 1;return;}pushdown ( t );int mid = ( l + r ) >> 1;if ( L <= mid )update ( t << 1, l, mid, L, R, v );if ( mid < R )update ( t << 1 | 1, mid + 1, r, L, R, v );tree[t].sum = tree[t << 1].sum + tree[t << 1 | 1].sum;if ( tree[t << 1].rcolor == tree[t << 1 | 1].lcolor )//判断左右儿子的相接处是否颜色一样 tree[t].sum --;tree[t].lcolor = tree[t << 1].lcolor;tree[t].rcolor = tree[t << 1 | 1].rcolor;
}noded query ( int t, int l, int r, int L, int R ) {if ( L <= l && r <= R )return tree[t];int mid = ( l + r ) >> 1;pushdown ( t );if ( R <= mid )return query ( t << 1, l, mid, L, R );else if ( mid < L )return query ( t << 1 | 1, mid + 1, r, L, R );else {noded ans, ans1 = query ( t << 1, l, mid, L, R ), ans2 = query ( t << 1 | 1, mid + 1, r, L, R );ans.lcolor = ans1.lcolor;ans.rcolor = ans2.rcolor;ans.sum = ans1.sum + ans2.sum;if ( ans1.rcolor == ans2.lcolor )ans.sum --;return ans;}
}void dfs1 ( int u, int fa, int depth ) {f[u] = fa;dep[u] = depth;Size[u] = 1;for ( int i = head[u];i != -1;i = edge[i].next ) {int v = edge[i].v;if ( v == fa )continue;dfs1 ( v, u, depth + 1 );Size[u] += Size[v];if ( Size[v] > Size[son[u]] || ! son[u] )son[u] = v;}
}void dfs2 ( int u, int t ) {top[u] = t;id[u] = ++ cnt;if ( ! son[u] )return;dfs2 ( son[u], t );for ( int i = head[u];i != -1;i = edge[i].next ) {int v = edge[i].v;if ( v != son[u] && v != f[u] )dfs2 ( v, v );}
}void solve ( int x, int y ) {int ans = 0, fx = top[x], fy = top[y];int xcolor = -1, ycolor = -1;noded ret;while ( fx != fy ) {if ( id[fx] < id[fy] ) {swap ( x, y );swap ( fx, fy );swap ( xcolor, ycolor );}ret = query ( 1, 1, cnt, id[fx], id[x] );ans += ret.sum;if ( ret.rcolor == xcolor )ans --;xcolor = ret.lcolor;x = f[fx];fx = top[x];}if ( id[x] > id[y] ) {swap ( x, y );swap ( xcolor, ycolor );}ret = query ( 1, 1, cnt, id[x], id[y] );ans += ret.sum;if ( xcolor == ret.lcolor )ans --;if ( ycolor == ret.rcolor )ans --;printf ( "%d\n", ans );
}void solve_update ( int x, int y, int c ) {int fx = top[x], fy = top[y];while ( fx != fy ) {if ( dep[fx] >= dep[fy] ) {update ( 1, 1, cnt, id[fx], id[x], c );x = f[fx];fx = top[x];}else {update ( 1, 1, cnt, id[fy], id[y], c );y = f[fy];fy = top[y];}}if ( id[x] <= id[y] )update ( 1, 1, cnt, id[x], id[y], c );elseupdate ( 1, 1, cnt, id[y], id[x], c );
}int main() {int n, m;memset ( head, -1, sizeof ( head ) );scanf ( "%d %d", &n, &m );for ( int i = 1;i <= n;i ++ )scanf ( "%d", &color[i] );for ( int i = 1;i < n;i ++ ) {int a, b;scanf ( "%d %d", &a, &b );addedge ( a, b );addedge ( b, a );}cnt = 0;dfs1 ( 1, 0, 1 );dfs2 ( 1, 0 );for ( int i = 1;i <= n;i ++ )update ( 1, 1, cnt, id[i], id[i], color[i] );char opt[2];int a, b, c;for ( int i = 1;i <= m;i ++ ) {scanf ( "%s %d %d", opt, &a, &b );if ( opt[0] == 'C' ) {scanf ( "%d", &c );solve_update ( a, b, c );}else solve ( a, b );}return 0;
}

看不懂的欢迎评论
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/318006.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ASP.NET Core 网站运行时修改设置如何自动生效

点击蓝字关注我在ASP.NET Core中&#xff0c;如果修改了appsettings.json中的设置&#xff0c;那么默认情况下就得重启网站才能生效。有没有办法在修改设置后自动刷新并应用呢&#xff1f;背景首先&#xff0c;我们看看默认模板建出来的 ASP.NET Core 网站&#xff0c;配置文件…

1022. 宠物小精灵之收服

1022. 宠物小精灵之收服 题意&#xff1a; 现在有n个胶囊&#xff0c;m个生命值&#xff0c;k个怪物&#xff0c;每个怪物需要a[i]个胶囊&#xff0c;且会造成b[i]个伤害后才能捕获&#xff0c;问在活着的前提下&#xff0c;最多捕获多少怪物&#xff0c;在怪物最多的情况下剩…

【周末狂欢赛6】[AT1219]历史研究(回滚莫队),大魔法师(矩阵+线段树),单峰排列

文章目录T1&#xff1a;单峰排列题目题解codeT2&#xff1a;历史研究题目题解codeT3&#xff1a;大魔法师题目题解code我可能这辈子都更不出来狂欢赛5了&#xff0c;先咕咕 T1&#xff1a;单峰排列 题目 一个n的全排列A[i]是单峰的&#xff0c;当且仅当存在某个x使得A[1]<…

YBTOJ:圈套问题(分治法、鸽笼原理)

文章目录题目描述数据范围解析代码图片转载自&#xff1a; https://blog.csdn.net/weixin_43346722/article/details/118435430题目描述 平面上有 n个点&#xff0c;用n个大小相同的圆分别将一个点作为圆心&#xff0c;同时满足圆圈不相交&#xff0c;求圆的最大半径。 数据范…

ASP.NET Core 实战:使用 NLog 将日志信息记录到 MongoDB

一、前言在项目开发中&#xff0c;日志系统是系统的一个重要组成模块&#xff0c;通过在程序中记录运行日志、错误日志&#xff0c;可以让我们对于系统的运行情况做到很好的掌控。同时&#xff0c;收集日志不仅仅可以用于诊断排查错误&#xff0c;由于日志同样也是大量的数据&a…

[学习笔记] 伸展树splay详解+全套模板+例题[Luogu P3369 【模板】普通平衡树]

文章目录引入概念全套模板变量声明updaterotate旋转splay操作insert插入delete删除查找x的位置查找第k大前驱/后继极小值-inf和极大值inf的作用例题&#xff1a;P3369 【模板】普通平衡树题目code声明一下&#xff0c;许多代码的注解都在模板代码里面写了的&#xff0c;所以正文…

手写AspNetCore 认证授权代码

在普通的MVC项目中 我们普遍的使用Cookie来作为认证授权方式&#xff0c;使用简单。登录成功后将用户信息写入Cookie&#xff1b;但当我们做WebApi的时候显然Cookie这种方式就有点不适用了。在dotnet core 中 WebApi中目前比较流行的认证授权方式是Jwt (Json Web Token) 技术。…

YBTOJ:采矿战略(线段树维护dp、树链剖分)

文章目录题目描述解析代码题目描述 所谓线段树维护dp&#xff0c;就是在线段树上维护dp &#xff08;逃&#xff09; 解析 把树剖一下后就变成了区间问题 考虑建一棵线段树&#xff0c;每一个结点都是一个背包 这样就能区间查询&#xff0c;也能带修了 这种做法复杂度其实并不…

【用皇宫三十六计生存法则带你走进LCT(动态树)】LCT概念+模板+例题【洛谷P3690 Link Cut Tree(动态树)】

文章目录LCT概念模板rotatoisrootsplayaccessmakerootsplitfindrootlinkcut封装版例题题目code普通版code封装版这篇博客主要是帮助大家理解各个模板及LCTLCTLCT的意思&#xff0c;方便理解&#xff0c;模板写法的理解在代码里有注释详解&#xff0c;如果要看原理的话&#xff…

迈向现代化的 .Net 配置指北

1. 欢呼 .NET Standard 时代我现在已不大提 .Net Core&#xff0c;对于我来说&#xff0c;未来的开发将是基于 .NET Standard&#xff0c;不仅仅是 面向未来 &#xff0c;也是 面向过去&#xff1b;不只是 .Net Core 可以享受便利&#xff0c; .NET Framework 不升级一样能享受…

YBTOJ洛谷P2042:维护数列(平衡树)

文章目录题目描述解析删除区间插入数列修改&翻转区间和&最大子段和代码传送门题目描述 解析 阴间题… 这不是裸的板子吗&#xff1f; 国赛真的有人能把这题写出来吗… 应该算一道练习作用很强的题了 写完这题&#xff0c;各种平衡树维护区间操作的方法可以说是毕业了吧…

CAP 2.4版本发布,支持版本隔离特性

前言自从上次 CAP 2.3 版本发布 以来&#xff0c;已经过去了几个月的时间&#xff0c;这几个月比较忙&#xff0c;所以也没有怎么写博客&#xff0c;趁着2019年到来之际&#xff08;现在应该是2019年开始的时候&#xff09;&#xff0c;CAP也发布了2018年的最后一个大版本 2.4&…

【周末狂欢赛7】【NOIP模拟赛】七夕祭,齿轮(dfs),天才黑客

文章目录T1题目题解codeT2题目题解codeT3题目题解codeT1 题目 七夕节因牛郎织女的传说而被扣上了「情人节」的帽子。于是TYVJ今年举办了一次线下七夕祭。Vani同学今年成功邀请到了cl同学陪他来共度七夕&#xff0c;于是他们决定去TYVJ七夕祭游玩。 TYVJ七夕祭和11区的夏祭的…

.NET Core 如何为项目提供高性能解决方案?

本系列&#xff0c;我们将探讨.NET Core 的一些好处&#xff0c;以及它如何为市场提供高性能解决方案&#xff0c;为传统.NET 开发人员和技术人员提供帮助。正文前言随着.NET Core 2.0 在 2016 年首次发布&#xff0c;微软拥有了这个通用、模块化、跨平台开源项目的下一个主要版…

[2.9训练]【CF909C】Python Indentation,【CF909D】Colorful Points,【CF909E】Coprocessor

文章目录T1&#xff1a;Python Indentation题目题解codeT2&#xff1a;Colorful Points题目题解codeT3&#xff1a;Coprocessor题目题解codeT1&#xff1a;Python Indentation 题目 题目描述 In Python, code blocks don’t have explicit begin/end or curly braces to mark…

Docker最全教程之使用Tencent Hub来完成CI(十)

本周更新两篇&#xff0c;保证不太监&#xff01;在本系列教程中&#xff0c;笔者希望将必要的知识点围绕理论、流程&#xff08;工作流程&#xff09;、方法、实践来进行讲解&#xff0c;而不是单纯的为讲解知识点而进行讲解。也就是说&#xff0c;笔者希望能够让大家将理论、…

[2.7]【CF933A】A Twisty Movement【CF926B】Add Points【CF917A】The Monster【CF919E】Congruence Equation

文章目录T1&#xff1a;A Twisty Movement题目题解codeT2&#xff1a;Add Points题目题解codeT3&#xff1a;The Monster题目题解codeT4&#xff1a;Congruence Equation题目题解codeT1&#xff1a;A Twisty Movement 题目 题目 题解 因为aia_iai​1/21/21/2&#xff0c;于…

LIS最长上升子序列

LIS算是比较经典的问题&#xff0c;常用的是O(n^2)的方法 for(int i1;i<n;i){dp[i]1;for(int j1;j<i;j){if(a[j]<a[i])dp[i]max(dp[i],dp[j]1);}mxmax(mx,dp[i]);}我们这里优化成O(nlogn) 我们模拟一个栈stack&#xff0c;每读入一个数&#xff0c;如果这个数大于栈顶…

EF Core 数据库 Provider 一览

当 EF Core 1.x 系列和 2.0 版本之间经过重大的重写时&#xff0c;所有 EF Core 数据库 Provider 都受到重创。从那时起&#xff0c;各种私人和商业开发团队一直在努力填补这个空白。正文当 EF Core 1.x 系列和 2.0 版本之间经过重大的重写时&#xff0c;所有 EF Core 数据库 P…

[3.3训练赛]One-Dimensional(矩阵快速幂),Freda的迷宫(无向图强连通分量+并查集),一道防AK好题

文章目录T1:One-DimensionaltitlesolutioncodeT2:【NOIP模拟赛】Freda的迷宫titlesolutioncodeT3:【NOIP模拟赛】一道防AK好题titlesolutioncode确实没想到自己写文章能隔这么久&#xff0c;鸽王预警 T1:One-Dimensional title 考虑一个含有 N 个细胞的一维细胞自动机。细胞…