70分, 不知道是哪里错了, 调了一天还没出来,求大佬调一下! 悬关
#include <bits/stdc++.h>
#define ls u << 1
#define rs u << 1 | 1
#define LL long long
#define inf 1000000000
using namespace std;
const int N = 5e5 + 10, mod = 1e9 + 7;
int a[N];
struct node{
int l, r, tag1[2], tag2[2], num[2], vis[2], add;
LL sum;
}tr[N << 2];
void make(int u, int x){
tr[u].sum = tr[u].sum + 1LL * (tr[u].r - tr[u].l + 1) * x;
tr[u].tag1[0] += x, tr[u].tag1[1] += x;
tr[u].tag2[0] += x, tr[u].tag2[1] += x;
tr[u].add += x;
}
void make1(int u, int x){
if(x >= tr[u].tag1[0]) return;
tr[u].sum = tr[u].sum - 1LL * tr[u].num[0] * (tr[u].tag1[0] - x);
if(tr[u].tag2[0] == tr[u].tag1[0]) tr[u].tag2[0] = x;
tr[u].tag1[0] = tr[u].vis[0] = x;
}
void make2(int u, int x){
if(x <= tr[u].tag2[0]) return;
tr[u].sum = tr[u].sum + 1LL * tr[u].num[1] * (x - tr[u].tag2[0]);
if(tr[u].tag1[0] == tr[u].tag2[0]) tr[u].tag1[0] = x;
tr[u].tag2[0] = tr[u].vis[1] = x;
}
/*
上次修改到 : 要加一个标记数组看看是否需要修改值
*/
void pushup(int u){
tr[u].sum = tr[ls].sum + tr[rs].sum;
tr[u].tag1[0] = max(tr[ls].tag1[0], tr[rs].tag1[0]);
if(tr[ls].tag1[0] == tr[rs].tag1[0]){
tr[u].tag1[1] = max(tr[ls].tag1[1], tr[rs].tag1[1]);
tr[u].num[0] = tr[ls].num[0] + tr[rs].num[0];
}
else{
tr[u].tag1[1] = min(tr[ls].tag1[0], tr[rs].tag1[0]);
tr[u].tag1[1] = max({tr[u].tag1[1], tr[ls].tag1[1], tr[rs].tag1[1]});
tr[u].num[0] = tr[ls].tag1[0] > tr[rs].tag1[0] ? tr[ls].num[0] : tr[rs].num[0];
}
tr[u].tag2[0] = min(tr[ls].tag2[0], tr[rs].tag2[0]);
if(tr[ls].tag2[0] == tr[rs].tag2[0]){
tr[u].tag2[1] = min(tr[ls].tag2[1], tr[rs].tag2[1]);
tr[u].num[1] = tr[ls].num[1] + tr[rs].num[1];
}
else{
tr[u].tag2[1] = max(tr[ls].tag2[0], tr[rs].tag2[0]);
tr[u].tag2[1] = min({tr[u].tag2[1], tr[ls].tag2[1], tr[rs].tag2[1]});
tr[u].num[1] = tr[ls].tag2[0] < tr[rs].tag2[0] ? tr[ls].num[1] : tr[rs].num[1];
}
}
void pushdown(int u){
if(tr[u].add != 0){
make(ls, tr[u].add), make(rs, tr[u].add);
tr[u].add = 0;
}
make1(ls, tr[u].tag1[0]), make1(rs, tr[u].tag1[0]);
make2(ls, tr[u].tag2[0]), make2(rs, tr[u].tag2[0]);
}
void build(int u, int l, int r){
if(l == r){
tr[u] = {l, r, {a[l], -inf}, {a[l], inf}, {1, 1}, {-inf, inf}, 0, 1LL * a[l]};
return;
}
tr[u] = {l, r, {-inf, -inf}, {inf, inf}, {0, 0}, {-inf, inf}, 0, 1LL * 0};
int mid = l + r >> 1;
build(ls, l, mid), build(rs, mid+1 ,r);
pushup(u);
}
void modifyadd(int u, int l, int r, int x){
if(tr[u].l >= l && tr[u].r <= r){
make(u, x);
return;
}
pushdown(u);
int mid = tr[u].l + tr[u].r >> 1;
if(l <= mid) modifyadd(ls, l, r, x);
if(r > mid) modifyadd(rs, l, r, x);
pushup(u);
}
void modifymin(int u, int l, int r, int x){
if(tr[u].tag1[0] <= x) return;
if(tr[u].l >= l && tr[u].r <= r && x > tr[u].tag1[1]){
make1(u, x);
return;
}
pushdown(u);
int mid = tr[u].l + tr[u].r >> 1;
if(l <= mid) modifymin(ls, l, r, x);
if(r > mid) modifymin(rs, l, r, x);
pushup(u);
}
void modifymax(int u, int l, int r, int x){
if(tr[u].tag2[0] >= x) return;
if(tr[u].l >= l && tr[u].r <= r && x < tr[u].tag2[1]){
make2(u, x);
return;
}
pushdown(u);
int mid = tr[u].l + tr[u].r >> 1;
if(l <= mid) modifymax(ls, l, r, x);
if(r > mid) modifymax(rs, l, r, x);
pushup(u);
}
LL querysum(int u, int l, int r){
if(tr[u].l >= l && tr[u].r <= r){
return tr[u].sum;
}
pushdown(u);
int mid = tr[u].l + tr[u].r >> 1;
LL res = 0;
if(l <= mid) res += querysum(ls, l, r);
if(r > mid) res += querysum(rs, l, r);
return res;
}
int querymax(int u, int l, int r){
if(tr[u].l >= l && tr[u].r <= r){
return tr[u].tag1[0];
}
pushdown(u);
int mid = tr[u].l + tr[u].r >> 1, res = -inf;
if(l <= mid) res = max(res, querymax(ls, l, r));
if(r > mid) res = max(res, querymax(rs, l, r));
return res;
}
int querymin(int u, int l, int r){
if(tr[u].l >= l && tr[u].r <= r){
return tr[u].tag2[0];
}
pushdown(u);
int mid = tr[u].l + tr[u].r >> 1, res = inf;
if(l <= mid) res = min(res, querymin(ls, l, r));
if(r > mid) res = min(res, querymin(rs, l, r));
return res;
}
void debug(int i){
cout << "----now----" << endl;
cout << tr[i].l << " " << tr[i].r << endl;
cout << tr[i].tag1[0] << " " << tr[i].tag1[1] << endl;
cout << tr[i].tag2[0] << " " << tr[i].tag2[1] << endl;
cout << tr[i].sum << endl;
cout << "----end----" << endl;
}
signed main()
{
// std::ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
int n; cin >> n;
for(int i = 1; i <= n; i++) cin >> a[i];
build(1, 1, n);
int m; cin >> m;
while(m--){
int op, l, r; cin >> op >> l >> r;
if(op == 1){
int x; cin >> x;
modifyadd(1, l, r, x);
}
else if(op == 2){
int x; cin >> x;
modifymax(1, l, r, x);
}
else if(op == 3){
int x; cin >> x;
modifymin(1, l, r, x);
}
else if(op == 4) printf("%lld\n", querysum(1, l, r));
else if(op == 5) printf("%d\n", querymax(1, l, r));
else if(op == 6) printf("%d\n", querymin(1, l, r));
}
return 0;
}