HDU -5893 List wants to travel

5.1 滑模控制(SMC)及其改进 本文系统阐述了滑模控制(SMC)的基本原理及其在永磁同步电机(PMSM)控制系统中的应用。首先介绍了滑模控制的核心思想,包括滑模面设计和不连续控制律,其强鲁棒性使其在电机控制领域得到广泛应用。其次分析了SMC在PMSM速度控制器和无位置传感器观测器中的具体实现方案。重点探讨了SMC固有的抖振问题,详细比较了边界层法、高阶滑模和自适应方法等多种改进策略的优缺点。最后指出改进SMC的研究趋势是多种策略的融合应用,如自适应高阶滑模等,以在保持鲁棒性的同时有效抑制抖振。 阅读详情

List wants to travel

Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 1521 Accepted Submission(s): 439

Problem Description
A boy named List who is perfect in English. Now he wants to travel and he is making a plan. But the cost of living in same citie always changes. Now he wants to know how many different kinds of continuous same cost he has to pay for living between two cities. Can you help him? (He is so lazy to do this by himself.)

Input
There are multiple cases. The first line contains two positive numbers N and M(N (N<=40000) where N is the amount of cities and M (M<=50000)) is the amount of operations.Then N-1 lines where each line have 3 integers a b and c, representing that there is a bidirectionoal road between city a and city b, and the cost is c.(a != b and c <= 100000). Then there are M lines of operation. For example, “Change a b c” means changing all the costs of the road which are passed by him when he travels from city a to city b to c. “Query a b” means he wants you to tell him how many different kinds of continuous same cost he has to pay traveling from city a to city b.(if a == b, the cost is 0).

Output
He insure you that there is exactly one route between every two different cities.

Sample Input
9 3
1 2 2
2 3 1
1 7 2
1 4 2
3 5 2
3 6 1
5 8 2
5 9 3
Query 1 8
Change 2 6 3
Query 1 6

Sample Output
3
2

Source
2016 ACM/ICPC Asia Regional Shenyang Online

树链剖分+线段树
难点和坑点在于怎么合并路径orz

合并区间的时候,我们是根据树链剖分把从起点到终点的路径一段一段合并
ans1从起点开始合并,所以新添加的一段路径应该添加在ans1的右边
ans2从终点开始合并,所以新添加的一段路径应该添加在ans2的左边
然后合并新的路径的时候,我们是把线段树上的一段段区间合并起来
如果是从起点开始合并的话,新的路径是从下往上的,也就是说dfs序是从大到小的
然而用线段树上添加的路径时候,我先查询的左区间,再查询的右区间,所以线段树查询到的段落的l和r是从小到大的
也就是说是线段树查询到的段落合并起来的路径在原来的树上,是从上往下的,dfs序从小到大
所以我们每在线段树上查询到一个段落都要把它左右端点交换一下,每次合并,新的都添加在原来的左边,这样合并出来的路径就是从下往上,是从起点开始走的路径
同理,从终点开始合并的话,新的路径应该是从上往下,dfs序从小到大,添加在ans2的左边。(模拟从终点走一遍就知道了)
所以如果是从终点开始合并的话,我们就不用翻转了,直接拿线段树上的合并就可以了,每次新添加的段落都添加在原来的右边

然后两条路径最终都合并到同一条重链上了。
如果两条路径相交在同一个点,则直接合并两条路径就可以了
如果ans2在下面,则还要合并一条从上往下的路径,所以直接合并线段树的就可以了,然后添加在ans1的右边,ans1再与ans2合并
如果ans1在下面,则还要合并一条从下往上的路径,所以直接合并线段树的就可以了,然后添加在ans1的右边,ans1再与ans2合并

#include<bits/stdc++.h>
using namespace std;
#define mem(a) memset(a,0,sizeof(a))

const int MAXN = 40100;
vector<int> g[MAXN];
int n,size[MAXN],dfn[MAXN],top[MAXN],son[MAXN],fa[MAXN],d[MAXN],num = 0,aa[MAXN];
map<pair<int,int>,int> w;

//树链剖分
void dfs1(int x)
{
	d[x] = d[fa[x]] + 1;
	size[x] = 1;
	for (int i = 0;i<g[x].size();i++)
	{
		int v = g[x][i];
		if (v == fa[x]) continue;
		fa[v] = x;
		dfs1(v);
		size[x] += size[v];
		if (size[v] > size[son[x]]) son[x] = v;
	}
}

void dfs2(int x,int tp)
{
	dfn[x] = ++num;
	top[x] = tp;
	aa[num] = w[make_pair(x,fa[x])];
	if (son[x]) dfs2(son[x],tp);
	for (int i = 0;i<g[x].size();i++)
		if (g[x][i] != fa[x] && g[x][i] != son[x]) dfs2(g[x][i],g[x][i]);
}
 
struct node{
	int l,r,lazy,num,nl,nr;
	int mid(){ return (r - l) / 2 + l;}
	void merge(node a,node b)//合并两个区间 
	{
		num = a.num + b.num;
		if (a.nr == b.nl && a.nr != -1 && b.nl != -1) num--;
		nl = a.nl; nr = b.nr;
	}
	void overturn() {swap(nr,nl);}//将区间顺序倒置 
	void write() //检验时用 
	{
		printf("%d %d %d %d %d %d\n",l,r,lazy,num,nl,nr);
	}
};

struct seg_tree{
	node tree[MAXN * 4];
	void build(int st,int ed,int x)//建树,lazy表示当前区间有没有被翻转,nl表示左端点的数字,nr表示右端点的数字,num表示有多少段颜色相同的 
	{
		tree[x].l = st;
		tree[x].r = ed;
		tree[x].lazy = -1;
		if (st == ed)
		{
			tree[x].nl = tree[x].nr = aa[st];
			tree[x].num = 1;
			if (st == 1)//建树的时候,一条边上两点,深度较大的那个点的dfn作为这条线段的dfn,所以根节点1没有对应的边 
			{
				tree[x].nl = tree[x].nr = -1;
				tree[x].num = 0;
			}
			return;
		}
		int mid = tree[x].mid();
		build(st,mid,x * 2);
		build(mid + 1,ed,x * 2 + 1);
		tree[x].merge(tree[x * 2],tree[x * 2 + 1]);
	}
	void modify(int st,int ed,int x,int c)//区间修改值 
	{
		if (tree[x].l >= st && tree[x].r <= ed)
		{
			tree[x].nl = tree[x].nr = c;
			tree[x].num = 1;
			tree[x].lazy = c;
			return;
		}
		if (tree[x].lazy != -1)
		{
			tree[x*2].lazy=tree[x*2+1].lazy=tree[x*2].nl=tree[x*2].nr=tree[x*2+1].nl=tree[x*2+1].nr=tree[x].lazy;
			tree[x * 2].num = tree[x * 2 + 1].num = 1;
			tree[x].lazy = -1;
		}
		int mid = tree[x].mid();
		if (mid >= st) modify(st,ed,x * 2,c);
		if (ed > mid) modify(st,ed,x * 2 + 1,c);
		tree[x].merge(tree[x * 2],tree[x * 2 + 1]);
	}
	node query(int st,int ed,int x,char c)//查询区间 
	{
		if (tree[x].l >= st && tree[x].r <= ed)
		{
			node temp = tree[x];
			if (c == 'L') temp.overturn();//如果是从起始点开始合并 
			return temp;
		}
		if (tree[x].lazy != -1)
		{
			tree[x*2].lazy=tree[x*2+1].lazy=tree[x*2].nl=tree[x*2].nr=tree[x*2+1].nl=tree[x*2+1].nr=tree[x].lazy;
			tree[x * 2].num = tree[x * 2 + 1].num = 1;
			tree[x].lazy = -1;
		}
		int mid = tree[x].mid();
		node ans;
		ans.nl = -1; ans.nr = -1; ans.num = 0;
		if (mid >= st) ans = query(st,ed,x * 2,c);
		if (ed > mid)
		{
			if (ans.num == 0) ans = query(st,ed,x * 2 + 1,c);
			else if (c == 'L') ans.merge(query(st,ed,x * 2 + 1,c),ans);
			else if (c == 'R') ans.merge(ans,query(st,ed,x * 2 + 1,c));
		}
		tree[x].merge(tree[x * 2],tree[x * 2 + 1]);
		return ans;
	}
}seg;


int mapping(int x,int y,int c)//c表示当前是修改还是查询 
{
	int fx = top[x],fy = top[y];
	node ans1,ans2;
	ans1.nl = ans1.nr = ans2.nl = ans2.nr = -1;//ans1表示从起始点开始合并,ans2表示从终点开始合并 
	ans1.num = ans2.num = 0;
	while (fx != fy)
	{
		if (d[fx] > d[fy])
		{
			if (c != -1) seg.modify(dfn[fx],dfn[x],1,c);
			else
			{
				if (ans1.num == 0) ans1 = seg.query(dfn[fx],dfn[x],1,'L'); //如果是从起点开始合并 
				else ans1.merge(ans1,seg.query(dfn[fx],dfn[x],1,'L'));
			}
			x = fa[fx];
			fx = top[x];
		}
		else
		{
			if (c != -1) seg.modify(dfn[fy],dfn[y],1,c);
			else
			{
				if (ans2.num == 0) ans2 = seg.query(dfn[fy],dfn[y],1,'R');//如果是从终点开始合并 
				else ans2.merge(seg.query(dfn[fy],dfn[y],1,'R'),ans2);
			}
			y = fa[fy];
			fy = top[y];
		}
	}
	if (x == y)//如果两条路径相交在同一个点 
	{
		if (c != -1) return 0;
		if (ans1.num == 0) return ans2.num;
		else if (ans2.num == 0) return ans1.num;
		ans1.merge(ans1,ans2);
		return ans1.num;
	}
	if (d[x] < d[y])//y在下面
	{
		if (c != -1)
		{
			seg.modify(dfn[x] + 1,dfn[y],1,c);
			return 0;
		}
		if (ans1.num == 0) ans1 = seg.query(dfn[x] + 1,dfn[y],1,'R');
		else ans1.merge(ans1,seg.query(dfn[x] + 1,dfn[y],1,'R'));
		if (ans2.num == 0) return ans1.num;
		else ans1.merge(ans1,ans2);
	}
	else//x在下面 
	{
		if (c != -1)
		{
			seg.modify(dfn[y] + 1,dfn[x],1,c);
			return 0;
		}
		if (ans1.num == 0) ans1 = seg.query(dfn[y] + 1,dfn[x],1,'L');
		else ans1.merge(ans1,seg.query(dfn[y] + 1,dfn[x],1,'L'));
		if (ans2.num != 0) ans1.merge(ans1,ans2);
	}
	return ans1.num;
}

int main()
{
	int n,p;
	while (scanf("%d%d",&n,&p) != EOF) 
	{
		for (int i = 1,u,v,t;i<=n-1;i++)
		{
			scanf("%d%d%d",&u,&v,&t);
			w[make_pair(u,v)] = t;
			w[make_pair(v,u)] = t;
			g[u].push_back(v);
			g[v].push_back(u);
		}
		dfs1(1);
		dfs2(1,1);
		char c[10];
		seg.build(1,n,1);
		while (p--)
		{
			scanf("%s",&c);
			if (c[0] == 'Q')
			{
				int u,v;
				scanf("%d%d",&u,&v);
				if (u == v)  printf("0\n");
				else printf("%d\n",mapping(u,v,-1));
			}
			else if (c[0] == 'C')
			{
				int u,v,t;
				scanf("%d%d%d",&u,&v,&t);
				int temptemp = mapping(u,v,t);
			}
		}
		for (int i = 1;i<=n;i++) g[i].clear();
		mem(son); mem(size); mem(d); mem(fa); mem(dfn); mem(top); mem(aa);
		num = 0;
		w.clear();
	}
}

这题是真的坑…线段树上的顺序也要注意一直都忽略了orz
调到心态小崩
蒟蒻瑟瑟发抖

YOLOv8改进:全网原创首发 | 新颖的多尺度卷积注意力(MSCA),即插即用,助力小目标检测 | NeurIPS2022 多尺度卷积注意力(MSCA),有效地提取上下文信息;1)作为注意力MSCA使用; 阅读详情

相关推荐

Windows安装WSL子系统及docker,以及WSL和docker配置、使用及问题解决

在Windows操作系统中,Ubuntu子系统(也称为Windows Subsystem for Linux, WSL)为开发者提供了一个在Windows环境下运行Linux环境的平台。然而,有时用户在按照Ubuntu子系统或者使用WSL时,可能会遇到各种问题,下面总结一下解决方式。想要在Windows上安装Docker(实际上是基于Hyper-V或者WSL2这两项虚拟化技术),需要开启虚拟化功能,所以不管是对于系统还是硬件都有一定的要求。

sym的博客 9781

HDU 5893 List wants to travel 【线段树+树链剖分】

#include<bits/stdc++.h> using namespace std; typedef vector<int> VI; typedef unsigned long long ull; typedef long long ll; typedef double db; const ll mod=1000000007; const int N=2e5+10; const int inf=

禅境花园 469

【03】海康MVS V4.3.0 ——安装教程、查看示例、库、头文件、开发指南

海康威视MVS机器视觉软件安装与使用指南:首先从官网下载MVS 4.3.0安装包,默认设置完成安装。安装后可在Development目录查看示例代码、开发文档及头文件,支持C++/C#/Python等多语言开发。软件内置虚拟相机功能,通过工具菜单添加虚拟设备后即可模拟真实相机操作,支持中英文界面切换、参数调节(曝光/增益等)及图像采集功能。虚拟相机虽仅能显示预设图像,但完整保留了参数调节功能,适合开发者进行功能测试。

程序员,他们想的是什么?他们想的永远都是技术,他们崇尚的也永远都是技术。 3305

Hdu-5893 List wants to travel(树链剖分)

Problem Description A boy named List who is perfect in English. Now he wants to travel and he is making a plan. But the cost of living in same citie always changes. Now he wants to know how many diff

WZJRJ28 470

手把手教你用GD32F407VET6的EXMC驱动外部SRAM,搞定大内存需求

本文详细介绍了如何使用GD32F407VET6的EXMC外设驱动外部SRAM,解决嵌入式开发中的大内存需求问题。通过硬件连接方案、EXMC时序配置与初始化步骤,以及软件集成与内存管理技巧,帮助开发者快速实现内存扩展。特别适合需要处理图形显示缓冲、音频处理等大内存场景的GD32F407开发者。

weixin_30752699的博客 346

别再折腾虚拟机了!手把手教你用WSL2在Windows 11上安装Kali Linux(含汉化与图形界面)

本文详细介绍了如何在Windows 11上通过WSL2安装和配置Kali Linux,包括汉化与图形界面设置。通过WSL2,用户可以享受接近原生性能的Linux体验,同时保持与Windows系统的无缝集成,特别适合网络安全爱好者和开发者。文章还提供了常见问题解决和性能优化建议,帮助用户高效使用Kali工具集。

weixin_42525369的博客 322

hdu5893 List wants to travel

裸的树链剖分加线段树区间修改 区间合并时需要多注意一点 当时写的很慢 理解不深刻 #include<bits/stdc++.h> using namespace std; const int INF = 0x3f3f3f3f; const int MAXN = 40005; #define lson l,m,rt<<1 #define rs...

diankeng5481的博客 182

基于java实现的弹幕视频网站

开发语言:Java框架:ssm技术:JSPJDK版本:JDK1.8服务器:tomcat7数据库:mysql 5.7(一定要5.7版本)数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包:Maven3.3.9系统展示弹幕视频网站,在弹幕视频网站可以查看首页、视频信息、商品信息、论坛信息、我的、跳转到后台、购物车、客服等内容前台首页界面图登录,通过登录填写账号、密码等信息进行登录操作登录界面图视频信息界面图。

DC5621的博客 1332

HDU 5893 List wants to travel(树链剖分+线段树)

Description 给出一棵nnn个点的树,每条边有颜色,mmm次操作,操作分两种 Change&nbsp;a&nbsp;b&nbsp;c:Change&nbsp;a&nbsp;b&nbsp;c:Change\ a\ b\ c:把从aaa点到bbb点路径上所有边的颜色变成ccc Query&nbsp;a&nbsp;b:Query&nbsp;a&nbsp;b:Query\ a\ b:查询a...

ZSQ 422

duilib 之 事件--bubbled冒泡事件应用、通用点击事件、进入离开事件、XML样式中直接添加事件

1. box 绑定点击事件 ui::Box *pSmallVideoBox = (ui::Box*)FindControl(L"rightBox"); if (pSmallVideoBox) { auto SwitchVideo = [this](ui::EventArgs* param){ m_bSecScreenIsScale = m_bMainScre...

目前打算换一个工作,有招聘windows c++方向的也欢迎联系,北京、济南 最好 972

Open3D——RANSAC拟合球面【2026最新版】

RANSAC三维点云球面拟合,博客长期更新,本文最新更新时间为:2026年3月5日。

点云侠的博客 4084

hdu 5893 List wants to travel 树链剖分 +线段树

http://acm.hdu.edu.cn/showproblem.php?pid=5893 题意: 题意:一棵无根树,两种操作:改变路径上的颜色,和询问路径上有多少段颜色。 裸的树链剖分+线段树维护颜色段, 唯一难点就是合并的时候 如果两个区间段颜色一样,ans--,链同理。   http://blog.youkuaiyun.com/viphong/article/details/5

缺氧 1079

骑砍Ⅱ霸主MOD开发(16)-FaceKey&BannerKey

摘要:本文介绍了FaceKey人物模型和BannerKey旗帜模型的生成流程。FaceKey通过序列化参数生成人物模型,包括头部(脸部、嘴、睫毛、眼睛)、眉毛、头发、身体和躯干等组件,每个部分通过特定标签和骨骼绑定实现。BannerKey则通过解析参数生成旗帜模型,包括模型、贴图和颜色等元素。两种模型都采用参数化设计和XML配置文件实现模型生成与定制。

骑砍战团&霸主MOD开发 2285

hdu5893List wants to travel

链接:http://acm.hdu.edu.cn/showproblem.php?pid=5893 题意:给定一棵n个节点的树,有边权。m个操作,操作1:给定a,b,求树上a到b上有多少个数字段(比如11233就是3段);操作2:给定a,b,c,将树上a到b路径上所有的边权全部修改为c。 分析:树链剖分,在查询时合并的时候注意一下细节即可。 代码: #include #include #i

Fsss 609

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

HDU 5893 List wants to travel

HDU 5893 List wants to travel树链剖分,边权题目给出2种操作 修改u到v的路径上的边的颜色为c 查询u到v的路径上有多少段颜色 思路根bzoj2243差不多,就是把点权改成边权。把边权下放到深度大的点的点权。维护起来没有想的复杂。先往重链头跳,跳完判断一下l是否跟r一样。一样说明汇合,不需要继续查了。否则查的时候要避开端点,可以查重儿子,看代码吧。代码树链剖分多组样例

P.H.S 255

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

[树链剖分] HDU 5893 List wants to travel

List wants to travel题意:给一棵树,每条边有个颜色,两种操作: Change a b c,把a到b的简单路径的边颜色变成c Query a b,查询a到b的简单路径有多少段颜色,连续相邻的同色边算一段。 思路:先建立树剖然后用线段树维护,记录一个区间内的颜色段数,最左颜色和最右颜色,然后就可以区间合并了,需要注意合并的顺序,没想清楚很容易就wa了,我想的是总是按查询的时间顺序把区

穹妹的家 604

jre9下载 jdk9

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

HDU 5893 List wants to travel 树链剖分求区间不同段个数

传送门:HDU5893 题意:给出一棵树和2种操作  1.修改u到v的路径上的边的颜色为c  2.查询u到v的路径上有多少段颜色(连续相同的颜色算一段) 思路:明显是树链剖分的题,难点在于维护颜色的连续性,在线段树中还好说,基本的线段树套路,左右区间邻接处比较一下就好了,关键是在询问过程中两边不断上移的过程,需要记录上一次询问的链的顶端颜色,和这一次询问链的底端颜色比较,看看是否能连成一段

WA是一笔财富 229

hdu5893 List wants to travel(树链剖分+线段树)

hdu5893http://blog.youkuaiyun.com/carryheart/article/details/52625012 参考队友的博客,总算看懂了,二次学习了,留个记录。

天道酬勤 388

HDU 5893 List wants to travel 树链剖分

题目:http://acm.hdu.edu.cn/showproblem.php?pid=5893题意:给定一棵树,树有边权,有两种操作: 改变两点之间路径上的边权为某个值 查询两点之间路径上的边权序列有多少个连续区间 思路:把边权映射到其邻接的两点中深度较大的点上去,树链剖分,线段上维护,线段树维护区间左端点和右端点颜色,合并时较麻烦。此题真正的难点在查询时,合并两个区间要判断端点颜色是否相同#i

弱智就要多努力 382

List wants to travel HDU - 5893

http://acm.hdu.edu.cn/showproblem.php?pid=5893 和hysbz一模一样 只是这道题给的是边权 边界处理比较麻烦 要小心一点 #include &lt;bits/stdc++.h&gt; using namespace std; struct node0 { int u; int v; int w; }; struct n...

sunyutian1998的博客 226

HDU 5893 List wants to travel 树链剖分 边权剖分

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5893题意:给出2种操作 1.修改u到v的路径上的边的颜色为c 2.查询u到v的路径上有多少段颜色将无根树边为有根树之后,对树进行树链剖分,得到每个点的编号 用边上深度大的节点表示边,这样就是一个树上点剖分 这样就和HYSBZ 2243一样了代码:#include <bits/stdc++.h>

SolarDomo的博客 634

hdu5893 List wants to travel(树链剖分+线段树)

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 270    Accepted Submission(s): 47 Problem Description A boy named List who is perf

新月 971

HDU 5893 List wants to travel(树链剖分)

【题目链接】http://acm.hdu.edu.cn/showproblem.php?pid=5893 【题目大意】   给出一棵树,每条边上都有一个边权,现在有两个操作,操作一要求将x到y路径上所有边更改为c权值,操作二要求查询x到y的路径上有几段连续的权值相同的。 【题解】   首先由于是边权,所以把所有边的存下来,做一遍剖分,将权值保存在每条边深度较深的点上,作...

weixin_30302609的博客 120

hdu 5893 List wants to travel 树链剖分求区间段数

用到树链剖分和线段树合并,线段数存储段数即需要包含左端点颜色右端点颜色和段数和,但是难点在树上的查询的时候会牵扯到 不同链之间的交接处是否重色,参考了别人的写法但是代码写的还是冗余度很高,好累,先放着吧,看以后有没有时间来精简下。#pragma comment(linker, "/STACK:1024000000,1024000000") #include <stdio.h> #include <s

Kblacksmith的博客 862
上一篇: HDU 6041 - I Curse Myself(仙人掌图DFS找环 + 有限队列求前k大)
下一篇: POJ 2763 - Housewife Wind
EIP_silly
博客等级 码龄8年 3粉丝 42原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值