这是一篇文章,熬了很久才做出来的。
只要熬过这篇,肯定能给初学者带来莫大的提升,给学c++的学者巩固知识。
#include<stdio.h>
#include<iostream>
using namespace std;
#define ll long long
const int n = 1e6 + 10;
ll sum[n << 2], ma[n << 2], se[n << 2], num[n << 2];//在这段中的l是L的小写。
ll ls(ll p) {
return p << 1;
};
ll rs(ll p) {
return p << 1 | 1;
}
void pushup(int p)
{
sum[p] = sum[ls(p)] + sum[rs(p)];
ma[p] = max(ma[ls(p)], ma[rs(p)]);
if (ma[ls(p)] == ma[rs(p)])
{
se[p] = max(se[ls(p)], se[rs(p)]);
num[p] = num[ls(p) + num[rs(p)]];
}
else {
se[p] = max(se[ls(p)], se[rs(p)]);
se[p] = max(se[p], min(ma[ls(p)], ma[rs(p)]));
num[p] = ma[ls(p)] > ma[rs(p)] ? num[ls(p)] : num[rs(p)];
}
}
void build(int p, int pl, int pr)
{
if (pl == pr)
{
scanf_s("%lld", &sum[p]);
ma[p] = sum[p];
se[p] = -1;
num[p] = 1;
return;
}
ll mid = (pl + pr) >> 1;
build(ls(p), pl, mid);
build(rs(p), pl, mid);
pushup(p);
}
void addtag(int p, int x)
{
if (x >= ma[p])return;
sum[p] -= num[p] * (ma[p] - x);
ma[p] = x;
}
void pushdown(int p)
{
addtag(ls(p), ma[p]);
addtag(rs(p), ma[p]);
}
void update(int l, int r, int p, int pl, int pr, int x)
{
if (x >= ma[p]) return;
if (l <= pl && pr <= r && se[p] < x)
{
addtag(p, x);
return;
}
pushdown(p);
ll mid = (pl + pr) >> 1;
if (l <= mid)
update(l, r, ls(p), pl, mid, x);
if (r > mid)
update(l, r, rs(p), mid + 1, pr, x);
pushup(p);
}
int querymax(int l, int r, int p, int pl, int pr)
{
if (pl >= l && r >= pr)
return ma[p];
pushdown(p);
int res = 0;
ll mid = (pl + pr) >> 1;
if (l <= mid)
res = querymax(l, r, ls(p), pl, mid);
if (r > mid)
res = max(res, querymax(l, r, rs(p), mid + 1, pr));
return res;
}
ll querysum(int l, int r, int p, int pl, int pr)
{
if (l <= pl && r >= pr)
return sum[p];
pushdown(p);
ll res = 0;
ll mid = (pl + pr) >> 1;
if (l <= mid)
res += querysum(l, r, ls(p), pl, mid);
if (r > mid)
{
res += querysum(l, r, rs(p), mid + 1, pr);
}
return res;
}
int main()
{
int t; scanf_s("%d", &t);
while (t--)
{
int n, m; scanf_s("%d%d", &n, &m);
build(1, 1, n);
while (m--)
{
int q, l, r, x;
scanf_s("%d%d%d", &q, &l, &r);
if (q == 0)
{
scanf_s("%d", &x);
update(l, r, 1, 1, n, x);
}
if (q == 1)
{
printf("%d\n", querymax(l, r, 1, 1, n));
}
if (q == 2)
{
printf("%lld\n", querysum(l, r, l, l, n));
}
}
}
return 0;
}
调试之后的运行结果为
该文章仅供学习。
如果对您有帮助,点个赞,关注我的博客并关注我的微信公众号:码文狙击所。您的关注是我们前进的动力。
关注我的微信公众号好不好嘛?谢谢了。