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;
}
归并排序晚点补

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

被折叠的 条评论
为什么被折叠?



