Leetcode_493_翻转对_线段树_归并排序

本文介绍了一种使用线段树进行区间修改并查询最大值的方法,通过具体实例展示了如何实现这一算法过程。适用于解决特定类型的数据结构题目。

11/28

没学过c++,看标程写的一堆class是真的hold不住QAQ
第一个想到的思路是线段树区间修改查询最大值
倒序遍历数组
将该元素的两倍加1到数组里的最大数这个区间+1
然后查询1(也可以是这个数组里的最小值)到这个数这个区间的最大值
把结果加到答案里
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e3 + 10;
int input[] = {0,1,3,2,3,1};
int n = 5;
struct node
{
	int l, r, sum;
	int lazytag;
} tree[4 * maxn];
void build(int i, int l, int r)
{
	tree[i].l = l;
	tree[i].r = r;
	if (l == r)
	{
		tree[i].sum = 0;
		return;
	}
	int mid = (l + r) / 2;
	build(i * 2, l, mid);
	build(i * 2 + 1, mid + 1, r);
	return;
}
void pushdown(int i)
{
	if (tree[i].lazytag != 0)
	{
		tree[i * 2].lazytag += tree[i].lazytag;
		tree[i * 2 + 1].lazytag += tree[i].lazytag;
		int mid = (tree[i].l + tree[i].r) / 2;
		tree[i * 2].sum += tree[i].lazytag;
		tree[i * 2 + 1].sum += tree[i].lazytag;
		tree[i].lazytag = 0;
	}
}
void add(int i, int l, int r, int k)
{
	if (tree[i].l > r || tree[i].r < l)
		return;
	if (tree[i].l >= l && tree[i].r <= r)
	{
		tree[i].sum += k;
		tree[i].lazytag += k;
		return;
	}
	pushdown(i);
	if (tree[2 * i].r >= l)
		add(2 * i, l, r, k);
	if (tree[2 * i + 1].l <= r)
		add(2 * i + 1, l, r, k);
	tree[i].sum =max( tree[2 * i].sum , tree[2 * i + 1].sum);
}
int search(int i, int l, int r)
{
	if (tree[i].r < l || tree[i].l > r)
		return 0;
	if (tree[i].l >= l && tree[i].r <= r)
		return tree[i].sum;
	pushdown(i);
	int sum = 0;
	if (tree[i << 1].r >= l)
		sum = max(sum, search(i * 2, l, r));
	if (tree[i << 1 | 1].l <= r)
		sum = max(sum, search(i * 2 + 1, l, r));
	return sum;
}
void test()
{
	for (int i = 1; i <= n; i++)
	{
		printf("%d %d %d %d\n", i,tree[i].l, tree[i].r,tree[i].sum);
	}
}
int main()
{
	int n = 5;
	int maxnum = 0;
	for (int i = 1; i <= n; i++)
		maxnum = max(input[i], maxnum);

	build(1, 1, maxnum);
	int ans = 0;
	for (int i = n; i >= 1; i--)
	{
		int a = input[i] * 2 + 1;
		if (a <= maxnum)
		{
			add(1, a, maxnum, 1);
		}
		cout << i << endl;
		test();
		cout << endl;
		ans += search(1, 1, input[i]);
	}
	cout << ans << endl;
	return 0;
}

归并排序晚点补

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值