Can you answer these queries III--线段树求最大连续子段和

题目链接:https://cn.vjudge.net/problem/SPOJ-GSS3

题目大意:n个数,m次操作,0,x,y,表示把a[x]位置的数改为y,1,x,y,表示求[x,y]的最大连续子段和。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N = 50010;
int n, m;
ll a[N];
struct node{
	int l, r;
	ll ls, rs, ms,sum;
}tr[N<<2];
void pushup(int m)
{
	tr[m].sum = tr[m<<1].sum + tr[m<<1|1].sum;
	tr[m].ls = max(tr[m<<1].ls, tr[m<<1].sum + tr[m<<1|1].ls);
	tr[m].rs = max(tr[m<<1|1].rs, tr[m<<1|1].sum + tr[m<<1].rs);
	tr[m].ms = max(tr[m<<1].rs + tr[m<<1|1].ls, max(tr[m<<1].ms, tr[m<<1|1].ms));
}
void build(int m, int l, int r)
{
	tr[m].l = l;
	tr[m].r = r;
	if(l == r)
	{
		tr[m].ls = tr[m].rs = tr[m].ms = tr[m].sum = a[l];
		return ;
	}
	int mid = (l + r) >> 1;
	build(m<<1, l, mid);
	build(m<<1|1, mid + 1, r);
	pushup(m);
}
void updata(int m, int id, ll val)
{
	if(tr[m].l == id && tr[m].r == id)
	{
		tr[m].ls = tr[m].rs = tr[m].ms = tr[m].sum = val;
		return ;
	}
	int mid = (tr[m].l + tr[m].r) >> 1;
	if(id <= mid)
		updata(m<<1, id, val);
	else
		updata(m<<1|1, id, val);
	pushup(m);
}
node ask(int m, int l, int r)
{
	if(tr[m].l == l && tr[m].r == r)
		return tr[m];
	int mid = (tr[m].l + tr[m].r) >> 1;
	if(r <= mid)
		return ask(m<<1, l, r);
	else if(l > mid)
		return ask(m<<1|1, l, r);
	else
	{
		node a, b, c;
		a = ask(m<<1, l, mid);
		b = ask(m<<1|1, mid + 1, r);
		c.sum = a.sum + b.sum;
		c.ls = max(a.ls, a.sum + b.ls);
		c.rs = max(b.rs, b.sum + a.rs);
		c.ms = max(a.rs + b.ls, max(a.ms, b.ms));
		return c;
	}
}
int main()
{
	while(~scanf("%d", &n))
	{
		for(int i = 1; i <= n; i++)
			scanf("%lld", &a[i]);
		build(1, 1, n);
		scanf("%d", &m);
		int op;
		while(m--)
		{
			scanf("%d", &op);
			if(op == 0)
			{
				int x;
				ll val;
				scanf("%d %lld", &x, &val);
				updata(1, x, val);
			}
			else
			{
				int l, r;
				scanf("%d %d", &l, &r);
				if(l > r)
					swap(l, r);
				node tmp = ask(1, l, r);
				printf("%lld\n", tmp.ms);
			}
		}
	}
	return 0;
}

 

内容概要:该论文聚焦于T2WI核磁共振图像超分辨率问题,提出了一种利用T1WI模态作为辅助信息的跨模态解决方案。其主要贡献包括:提出基于高频信息约束的网络框架,通过主干特征提取分支高频结构先验建模分支结合Transformer模块注意力机制有效重建高频细节;设计渐进式特征匹配融合框架,采用多阶相似特征匹配算法提高匹配鲁棒性;引入模型量化技术降低推理资源需。实验结果表明,该方法不仅提高了超分辨率性能,还保持了图像质量。 适合人群:从事医学图像处理、计算机视觉领域的研究人员工程师,尤其是对核磁共振图像超分辨率感兴趣的学者技术开发者。 使用场景及目标:①适用于需要提升T2WI核磁共振图像分辨率的应用场景;②目标是通过跨模态信息融合提高图像质量,解决传统单模态方法难以克服的高频细节丢失问题;③为临床诊断提供更高质量的影像资料,帮助医生更准确地识别病灶。 其他说明:论文不仅提供了详细的网络架构设计与实现代码,还深入探讨了跨模态噪声的本质、高频信息约束的实现方式以及渐进式特征匹配的具体过程。此外,作者还对模型进行了量化处理,使得该方法可以在资源受限环境下高效运行。阅读时应重点关注论文中提到的技术创新点及其背后的原理,理解如何通过跨模态信息融合提升图像重建效果。
### 最大算法的 C++ 实现 最大问题是经典的动态规划问题之一,其目标是从给定的一维数组中找到连续数组的最大。以下是几种常见的 C++ 实现方式。 #### 方法一:基于动态规划的经典实现 此方法通过维护一个 `dp` 数组来存储当前最优解的状态转移方程为 \( dp[i] = \max(dp[i-1] + arr[i], arr[i]) \)[^1]。最终结果可以通过遍历整个 `dp` 数组得到最大值。 ```cpp #include <iostream> #include <vector> #include <algorithm> using namespace std; void MaximumSum(vector<int> V) { int size = V.size(); int DP[size + 1]; // 初始化 DP 数组 for (int i = 0; i <= size; ++i) DP[i] = 0; // 动态规划计算过程 for (int i = 1; i <= size; ++i) { DP[i] = max(DP[i - 1] + V[i - 1], V[i - 1]); } // 输出中间状态(可选) cout << "不同长度下的最大分别为:" << endl; for (int i = 0; i <= size; ++i) cout << DP[i] << " "; cout << endl; // 找到全局最大值 int answer = 0; for (int i = 0; i <= size; ++i) { if (DP[i] > answer) answer = DP[i]; } cout << "最大为: " << answer << endl; } int main() { vector<int> V; int n, temp; cin >> n; for (int i = 0; i < n; ++i) { cin >> temp; V.push_back(temp); } MaximumSum(V); return 0; } ``` --- #### 方法二:空间复杂度优化版本 为了减少额外的空间开销,可以仅使用两个变量代替完整的 `dp` 数组。这种方法的核心思想是实时更新当前的最大以及整体的最大值[^2]。 ```cpp #include <bits/stdc++.h> using namespace std; int main(){ ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); long long n, maxx = LLONG_MIN, a, s = 0; cin >> n; for(int i = 1; i <= n; ++i){ cin >> a; if(s > 0){ s += a; } else{ s = a; } maxx = max(maxx, s); } cout << maxx; return 0; } ``` --- #### 方法三:带有起始与结束索引的实现 除了返回最大外,还可以进一步扩展功能以获取对应的起始终止位置[^3]。 ```cpp #include <iostream> #include <vector> using namespace std; struct Result { int sum; int startIndex; int endIndex; }; Result maxSubArray(const vector<int>& nums) { int currentMax = 0; int globalMax = INT_MIN; int start = 0, end = 0, s = 0; for (size_t i = 0; i < nums.size(); ++i) { if (currentMax >= 0) { currentMax += nums[i]; } else { currentMax = nums[i]; s = i; } if (globalMax < currentMax) { globalMax = currentMax; start = s; end = i; } } return {globalMax, start, end}; } int main() { vector<int> nums; int num; cout << "输入数据:"; while (cin >> num && cin.peek() != '\n') { nums.push_back(num); } auto result = maxSubArray(nums); cout << "最大:" << result.sum << "\n"; cout << "起始位置:" << result.startIndex + 1 << "\n"; cout << "终止位置:" << result.endIndex + 1 << "\n"; return 0; } ``` --- #### 方法四:完整版带打印路径的结果 如果不仅需要知道最大,还需要输出具体的数组,则可以在动态规划过程中记录路径信息并回溯获得具体区间[^4]。 ```cpp #include <iostream> using namespace std; const int MAXN = 1e5 + 7; long long a[MAXN]; pair<long long, pair<int, int>> maxFind(int n) { long long b = 0, sum = LLONG_MIN; int bestStart = 0, bestEnd = 0, currentStart = 0; for (int j = 0; j < n; ++j) { if (b > 0) { b += a[j]; } else { b = a[j]; currentStart = j; } if (b > sum) { sum = b; bestStart = currentStart; bestEnd = j; } } cout << "最大为: "; for (int k = bestStart; k <= bestEnd; ++k) { cout << a[k] << ' '; } cout << endl; return {sum, {bestStart, bestEnd}}; } int main() { int n; cin >> n; for (int i = 0; i < n; ++i) cin >> a[i]; pair<long long, pair<int, int>> res = maxFind(n); cout << "最大为: " << res.first << endl; return 0; } ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值