UVA - 11992 Fast Matrix Operations

本文详细记录了作者在解决复杂数据结构问题时遇到的挑战及解决方案,特别是在使用线段树和懒惰传播技术时的常见错误和调试技巧。通过实例分析,作者分享了如何避免节点标记混乱、初始化不当、更新顺序错误等问题,并强调了freopen函数在调试过程中的注意事项。

WA到哭啊,怎么还不过,从下午6点搞到晚上10点,怎么一直WA啊!

------------------------------------------------------------------------------------------------------------------------------

偶,耶,****,fuck,终于过了啊,原来最大的bug是freopen,囧囧囧。

说一次本蒟蒻错的好几个点

1.在每个节点上附上20+个标记值,作为20+颗线段树,第一次写注意写法,极易混淆。

2.setmark初始值要设为-1,不能设为0,每次更改后也要设为-1。

3.max和min要在每次操作的同时更新,要用新的函数求max,min,不能在原函数query上搞。

4.这个时候过了案例,但是对比自己搞的案例,发现在set后,原来的add值还是有效的,开始思考先后关系,set覆盖add,add可以在set后搞,所以每次set完一定要把set的节点的两个子节点的addmark清0!!!,在这里WA到死。

5.调试完程序freopen一定要删了啊,fuck,WA到爆炸啊,测了好久一直没测出问题。

AC代码

#include <iostream>
#include <algorithm>
#define ll long long
#define lson left,mid,k<<1,f
#define rson mid+1,right,k<<1|1,f
#define imid int mid=(left+right)>>1
using namespace std;
struct node
{
	int l[21];
	int r[21];
	ll sum[21];
	ll minn[21];
	ll maxn[21];
	ll addmark[21];
	ll setmark[21];
}que[200005 * 4];
int ql, qr;
ll val;
void up(int k, int f)
{
	que[k].sum[f] = que[k << 1].sum[f] + que[k << 1 | 1].sum[f];
	que[k].minn[f] = min(que[k << 1].minn[f], que[k << 1 | 1].minn[f]);
	que[k].maxn[f] = max(que[k << 1].maxn[f], que[k << 1 | 1].maxn[f]);
}
void down(int k, int f)
{
	if (que[k].setmark[f] >= 0)
	{
		//que[k].addmark[f] = 0;//不需要
		que[k << 1].addmark[f] = 0;//需要
		que[k << 1 | 1].addmark[f] = 0;//需要
		que[k << 1].setmark[f] = que[k].setmark[f];
		que[k << 1 | 1].setmark[f] = que[k].setmark[f];
		que[k << 1].sum[f] = que[k].setmark[f] * (que[k << 1].r[f] - que[k << 1].l[f] + 1);
		que[k << 1 | 1].sum[f] = que[k].setmark[f] * (que[k << 1 | 1].r[f] - que[k << 1 | 1].l[f] + 1);
		que[k << 1].maxn[f] = que[k].setmark[f];
		que[k << 1].minn[f] = que[k].setmark[f];
		que[k << 1 | 1].maxn[f] = que[k].setmark[f];
		que[k << 1 | 1].minn[f] = que[k].setmark[f];
		que[k].setmark[f] = -1;
	}
	if (que[k].addmark[f])
	{
		que[k << 1].addmark[f] += que[k].addmark[f];
		que[k << 1 | 1].addmark[f] += que[k].addmark[f];
		que[k << 1].sum[f] += que[k].addmark[f] * (que[k << 1].r[f] - que[k << 1].l[f] + 1);
		que[k << 1 | 1].sum[f] += que[k].addmark[f] * (que[k << 1 | 1].r[f] - que[k << 1 | 1].l[f] + 1);
		que[k << 1].maxn[f] += que[k].addmark[f];
		que[k << 1].minn[f] += que[k].addmark[f];
		que[k << 1 | 1].maxn[f] += que[k].addmark[f];
		que[k << 1 | 1].minn[f] += que[k].addmark[f];
		que[k].addmark[f] = 0;
	}
}
void build(int left, int right, int k, int f)
{
	que[k].l[f] = left;
	que[k].r[f] = right;
	que[k].addmark[f] = 0;
	que[k].setmark[f] = -1;//初值 = -1
	que[k].minn[f] = 0;
	que[k].maxn[f] = 0;
	if (left == right)
	{
		que[k].sum[f] = 0;
		return;
	}
	imid;
	build(lson);
	build(rson);
	up(k, f);
}
void updateadd(int left, int right, int k, int f)
{
	if (qr < left || right < ql)
		return;
	if (ql <= left && right <= qr)
	{
		que[k].addmark[f] += val;
		que[k].sum[f] += val * (que[k].r[f] - que[k].l[f] + 1);
		que[k].maxn[f] += val;
		que[k].minn[f] += val;
		return;
	}
	imid;
	down(k, f);
	updateadd(lson);
	updateadd(rson);
	up(k, f);
}
void updateset(int left, int right, int k, int f)
{
	if (qr < left || right < ql)
		return;
	if (ql <= left && right <= qr)
	{
		que[k].setmark[f] = val;
		que[k].addmark[f] = 0;
		que[k].sum[f] = val * (que[k].r[f] - que[k].l[f] + 1);
		que[k].maxn[f] = val;
		que[k].minn[f] = val;
		return;
	}
	imid;
	down(k, f);
	updateset(lson);
	updateset(rson);
	up(k, f);
}
ll query(int left, int right, int k, int f)
{
	if (qr < left || right < ql)
		return 0;
	if (ql <= left && right <= qr)
		return que[k].sum[f];
	imid;
	down(k, f);
	return query(lson) + query(rson);
}
ll querymax(int left, int right, int k, int f)
{
	if (qr < left || right < ql)
		return 0;
	if (ql <= left && right <= qr)
		return que[k].maxn[f];
	imid;
	down(k, f);
	return max(querymax(lson), querymax(rson));
}
ll querymin(int left, int right, int k, int f)
{
	if (qr < left || right < ql)
		return 9999999999;
	if (ql <= left && right <= qr)
		return que[k].minn[f];
	imid;
	down(k, f);
	return min(querymin(lson), querymin(rson));
}
int main()
{
	int r, c, m;
	int op, q1, q2, w1, w2;
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w+", stdout);
	while (scanf("%d%d%d", &r, &c, &m) > 0)
	{
		if (r == 0)
			return 0;
		for (int i = 1; i <= r; i++)
			build(1, c, 1, i);
		while (m--)
		{
			scanf("%d", &op);
			if (op == 1)
			{
				scanf("%d%d%d%d%lld", &q1, &w1, &q2, &w2, &val);
				ql = w1;
				qr = w2;
				for (int i = q1; i <= q2; i++)
					updateadd(1, c, 1, i);
			}
			else if (op == 2)
			{
				scanf("%d%d%d%d%lld", &q1, &w1, &q2, &w2, &val);
				ql = w1;
				qr = w2;
				for (int i = q1; i <= q2; i++)
					updateset(1, c, 1, i);
			}
			else if (op == 3)
			{
				ll ans = 0, minn = 9999999999, maxn = 0;
				scanf("%d%d%d%d", &q1, &w1, &q2, &w2);
				ql = w1;
				qr = w2;
				for (int i = q1; i <= q2; i++)
				{
					ans += query(1, c, 1, i);
					minn = min(minn, querymin(1, c, 1, i));
					maxn = max(maxn, querymax(1, c, 1, i));
				}
				printf("%lld %lld %lld\n", ans, minn, maxn);
			}
		}
	}
}

 

提供了一个详细的MATLAB仿真程序,用于实现自回归(AR)模型的功率谱估计。该程序基于经典的数字信号处理教材——《数字信号处理理论、算法与实现》第三版中的相关内容(第545-547页),旨在帮助学习者理解和实践AR模型在功率谱估计中的应用。 简介 AR模型是一种常用的时间序列分析方法,通过建立当前值与其过去值之间的线性关系来描述时间序列的动态特性。功率谱估计是信号处理中的关键环节,用于揭示信号频率成分的分布。本仿真通过自相关方法实现AR模型参数的估计,并进而计算信号的功率谱。 特点 含详细注释:代码中添加了丰富的注释,便于初学者理解每一步的计算逻辑和目的。 参数可调:用户可根据需要调整AR模型的阶数(p值)、信号长度等参数,以适应不同的信号分析需求。 理论联系实际:通过将书本知识转化为实践操作,加深对AR模型及其在功率谱估计中应用的理解。 使用说明 环境要求:确保你的计算机上已安装MATLAB,并且版本适合运行提供的脚本。 加载脚本:将提供的MATLAB文件导入到MATLAB的工作环境中。 修改配置:根据需要修改代码中的参数配置,如AR模型的阶数等。 运行仿真:执行脚本,观察并分析输出结果,包括自回归模型的系数以及估算出的功率谱。 学习与分析:通过对比不同参数下的结果,深入理解AR模型在功率谱估计中的行为。 注意事项 在使用过程中,可能需要基础的数字信号处理知识以便更好地理解代码背后的数学原理。 请确保你的MATLAB环境已正确设置,能够支持脚本中的所有函数和运算。 结论 此资源对于研究信号处理、通信工程或是进行相关学术研究的学生和科研人员来说是一个宝贵的工具。它不仅提供了理论知识的具体实现,也是提升实践技能的优秀案例。通过动手操作,你将更加熟练地掌握AR模型及其在功率谱估计中的应用技巧。 开始探索,深入了解AR模型的力量,解开信号隐藏的秘密吧!
提供了关于时间序列分析与预测的宝贵资源,特别聚焦于**自回归积分滑动平均模型(ARIMA)**及其应用。对于那些希望深入理解并实践时间序列建模的学者、研究人员以及数据分析爱好者来说,这是一个不可或缺的学习材料。本资源不仅包括了详细的理论讲解,涵盖了时间序列分析的基础,如移动平均(MA)、自回归(AR)、指数平滑等关键概念,而且通过具体的ARIMA模型解析,搭配MATLAB编程实现实例,帮助用户从理论到实践全面掌握这一重要统计工具。 内容概览 理论讲解: 深入浅出地介绍了时间序列分析的基本原理,重点阐述ARIMA模型的构建步骤,包括如何识别模型的参数(p,d,q),以及其在处理非平稳数据中的作用。 MATLAB代码实现: 提供了多个ARIMA模型的MATLAB实现示例,这些代码覆盖了从数据准备、模型拟合、诊断检验到预测的全过程,是学习如何利用MATLAB进行时间序列分析的实用工具。 实例分析: 包括不同行业或领域的实际案例研究,展示如何应用ARIMA及其它时间序列方法解决真实世界的数据预测问题,增强理解和应用能力。 文件结构 时间序列模型ARIMA的讲解与matlab代码实现(含多个实例).rar: 主要资源压缩包,解压后包含文档和MATLAB代码文件夹。 文档: 提供了理论知识讲解。 MATLAB代码: 实现了文中讨论的各种模型,附带注释,便于理解与修改。 使用指南 下载资源: 点击下载“时间序列模型ARIMA的讲解与matlab代码实现(含多个实例).rar”文件。 解压文件: 解压缩至本地,确保你可以访问文档和代码。 环境准备: 确保你的电脑上已安装MATLAB,并熟悉基本操作。 学习流程: 首先阅读文档理解时间序列分析的理论基础,然后逐步跟随MATLAB代码示例进行实践。 实践应用: 尝试将所学应用到自己的数据集上,调整参数以优化模型性能。 注意事项 请根据M
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值