从零开始学算法/C++/Start
今天学会了线段树,线段树实在是太难了,不过很好用
[https://www.acwing.com/problem/content/246/](AcWing 245 你能回答这些问题吗)
明天尝试学到算法竞赛进阶指南p245,然后再把洛谷题单里面线段树题单刷完,说实话很有难度。
洛谷的题目和数据太有水平了。
下面是该题代码
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 5e5 + 1;
int w[N];
struct node
{
int l, r, lmax, rmax, sum, data;
}t[N << 2];
void build(int p, int l, int r)
{
t[p] = { l,r };
if (l == r) { t[p] = { l,l,w[l],w[l],w[l],w[l] }; return; }
int mid = l + r >> 1;
build(p << 1, l, mid), build(p << 1 | 1, mid + 1, r);
t[p].sum = t[p << 1].sum + t[p << 1 | 1].sum;
t[p].lmax = max(t[p << 1].lmax, t[p << 1].sum + t[p << 1 | 1].lmax);
t[p].rmax = max(t[p << 1 | 1].rmax, t[p << 1 | 1].sum + t[p << 1].rmax);
t[p].data = max(t[p << 1].rmax + t[p << 1 | 1].lmax, max(t[p << 1].data, t[p << 1 | 1].data));
}
node ffind(int p, int l, int r)
{
if (l <= t[p].l && t[p].r <= r)return t[p];
int mid = t[p].l + t[p].r >> 1;
if (r <= mid)return ffind(p << 1, l, r);
else if (l > mid)return ffind(p << 1 | 1, l, r);
else
{
node a, b, c;
a = ffind(p << 1, l, r);
b = ffind(p << 1 | 1, l, r);
c.sum = a.sum + b.sum;
c.lmax = max(a.lmax, a.sum + b.lmax);
c.rmax = max(b.rmax, b.sum + a.rmax);
c.data = max(a.rmax + b.lmax, max(a.data, b.data));
return c;
}
}
void modify(int p, int x, int k)
{
if (t[p].l == t[p].r) { t[p] = { t[p].l,t[p].r,k,k,k,k }; return; }
int mid = t[p].l + t[p].r >> 1;
if (x <= mid)modify(p << 1, x, k);
else modify(p << 1 | 1, x, k);
t[p].sum = t[p << 1].sum + t[p << 1 | 1].sum;
t[p].lmax = max(t[p << 1].lmax, t[p << 1].sum + t[p << 1 | 1].lmax);
t[p].rmax = max(t[p << 1 | 1].rmax, t[p << 1 | 1].sum + t[p << 1].rmax);
t[p].data = max(t[p << 1].rmax + t[p << 1 | 1].lmax, max(t[p << 1].data, t[p << 1 | 1].data));
}
int n, m, k, x, y;
int main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
cin >> n >> m;
for (int i = 1; i <= n; ++i)cin >> w[i];
build(1, 1, n);
while (m--)
{
cin >> k >> x >> y;
if (k == 1)
{
if (x > y)swap(x, y);
cout << ffind(1, x, y).data << endl;
}
else modify(1, x, y);
}
return 0;
}