QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#293006#5069. Vacation_LAP_WA 718ms141520kbC++146.0kb2023-12-28 19:32:442023-12-28 19:32:45

Judging History

你现在查看的是最新测评结果

  • [2023-12-28 19:32:45]
  • 评测
  • 测评结果:WA
  • 用时:718ms
  • 内存:141520kb
  • [2023-12-28 19:32:44]
  • 提交

answer

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;

const int N = 4e5 + 10;
const long long INF = 0x3f3f3f3f3f3f3f3fLL;
int n, m, c, A[N], B;

#define lc (u << 1)
#define rc (u << 1 | 1)
#define mid ((l + r) >> 1)
struct Max_Seg {
    ll C[N << 2];
    void Modify(int u, int l, int r, int p, ll x) {
        if(l == r) return C[u] = x, void();
        if(p <= mid) Modify(lc, l, mid, p, x);
        else Modify(rc, mid + 1, r, p, x);
        C[u] = max(C[lc], C[rc]);
    }
    ll Ask(int u, int l, int r, int L, int R) {
        if(l >= L && r <= R) return C[u];
        if(mid >= R) return Ask(lc, l, mid, L, R);
        if(mid < L) return Ask(rc, mid + 1, r, L, R);
        return max(Ask(lc, l, mid, L, R), Ask(rc, mid + 1, r, L, R));
    }
} Block, Other;
namespace SegmentTree {
    struct node {
        ll l, r, s, v;
        node(ll _v = 0) {l = r = v = max(_v, 0ll), s = _v; }
        node(ll _l, ll _r, ll _s, ll _v): l(_l), r(_r), s(_s), v(_v) {}
    };
    node operator + (const node &lhs, const node &rhs) {
        return node(max(lhs.l, lhs.s + rhs.l), max(rhs.r, rhs.s + lhs.r), lhs.s + rhs.s,
                max(lhs.r + rhs.l, max(lhs.v, rhs.v)));
    }
    node T[N << 2];
    void Build(int u, int l, int r) {
        if(l != r) 
            Build(lc, l, mid), Build(rc, mid + 1, r), T[u] = T[lc] + T[rc];
        else T[u] = node(A[l]);
    }
    void Modify(int u, int l, int r, int p, ll x) {
        if(l == r) return T[u] = node(x), void();
        if(p <= mid) Modify(lc, l, mid, p, x);
        else Modify(rc, mid + 1, r, p, x);
        T[u] = T[lc] + T[rc];
    }
    node Ask(int u, int l, int r, int L, int R) {
        if(l >= L && r <= R) return T[u];
        if(mid >= R) return Ask(lc, l, mid, L, R);
        if(mid < L) return Ask(rc, mid + 1, r, L, R);
        return Ask(lc, l, mid, L, R) + Ask(rc, mid + 1, r, L, R);
    }
}
struct Little_SegTree {
    struct node {
        ll ans, pre, suf;
        node(ll _ans = -INF, ll _pre = 0, ll _suf = 0): ans(_ans), pre(_pre), suf(_suf) {}
        node operator + (const node &rhs) {
            return node(max(this->pre + rhs.suf, max(this->ans, rhs.ans)), max(this->pre, rhs.pre), max(this->suf, rhs.suf));
        }
    };
    node *T; ll *tag_pre, *tag_suf;
    inline void init(int n) {
        T = (node*)calloc(n << 2, sizeof(node));
        tag_pre = (ll*)calloc(n << 2, sizeof(ll));
        tag_suf = (ll*)calloc(n << 2, sizeof(ll));
    }
    void Build(int u, int l, int r, ll pre[], ll suf[]) {
        tag_pre[u] = tag_suf[u] = 0;
        if(l != r) {
            Build(lc, l, mid, pre, suf), Build(rc, mid + 1, r, pre, suf);
            T[u] = T[lc] + T[rc];
        } else T[u] = node(pre[l] + suf[l], pre[l], suf[l]);
    }
    inline void Tag(int u, ll a, ll b) {
        tag_pre[u] += a, tag_suf[u] += b;
        T[u].pre += a, T[u].suf += b, T[u].ans += a + b;
    }
    inline void pushdown(int u) {
        if(!tag_pre[u] && !tag_suf[u]) return;
        Tag(lc, tag_pre[u], tag_suf[u]), Tag(rc, tag_pre[u], tag_suf[u]);
        tag_pre[u] = tag_suf[u] = 0;
    }
    void Add(int u, int l, int r, int L, int R, ll a, ll b) {
        if(l >= L && r <= R) return Tag(u, a, b);
        pushdown(u);
        if(mid >= L) Add(lc, l, mid, L, R, a, b);
        if(mid < R) Add(rc, mid + 1, r, L, R, a, b);
        T[u] = T[lc] + T[rc];
    }
    node Ask(int u, int l, int r, int L, int R) {
        if(l >= L && r <= R) return T[u];
        pushdown(u);
        if(mid >= R) return Ask(lc, l, mid, L, R);
        if(mid < L) return Ask(rc, mid + 1, r, L, R);
        return Ask(lc, l, mid, L, R) + Ask(rc, mid + 1, r, L, R);
    }
} Tree[N];
#undef lc
#undef rc
#undef mid

int L[N], R[N], ID[N];

int main() {
    ios::sync_with_stdio(false), cin.tie(0);

    cin >> n >> m >> c;
    for(int i = 1; i <= n; i ++) cin >> A[i];
    n = (n + c - 1) / c * c, B = n / c;
    SegmentTree::Build(1, 1, n);
    
    for(int i = 1; i <= B; i ++) {
        static long long pre[N], suf[N];
        L[i] = (i - 1) * c + 1, R[i] = i * c;
        for(int j = L[i]; j <= R[i]; j ++) ID[j] = i;
        Block.Modify(1, 1, B, i, SegmentTree::Ask(1, 1, n, L[i], R[i]).v);
        if(i > 1) {
            pre[0] = suf[c] = 0;
            for(int j = 1; j <= c; j ++) pre[j] = pre[j - 1] + A[L[i] - j];
            for(int j = c - 1; j >= 0; j --) suf[j] = suf[j + 1] + A[L[i] + c - j - 1];
            Tree[i].init(c + 1); Tree[i].Build(1, 0, c, pre, suf);
            Other.Modify(1, 1, B, i, Tree[i].T[1].ans);
        }
    }

    while(m --) {
        int op, x, y; cin >> op >> x >> y;
        if(op == 1) {
            SegmentTree::Modify(1, 1, n, x, y);
            Block.Modify(1, 1, B, ID[x], SegmentTree::Ask(1, 1, n, L[ID[x]], R[ID[x]]).v);
            int pos = x - L[ID[x]];
            if(ID[x] > 1) {
                Tree[ID[x]].Add(1, 0, c, 0, c - pos, 0, y - A[x]);
                Other.Modify(1, 1, B, ID[x], Tree[ID[x]].T[1].ans);
            }
            if(ID[x] < B) {
                Tree[ID[x] + 1].Add(1, 0, c, R[ID[x]] - x + 1, c, y - A[x], 0);
                Other.Modify(1, 1, B, ID[x] + 1, Tree[ID[x] + 1].T[1].ans);
            }
            A[x] = y;
        } else {
            if(y - x + 1 > c) {
                ll ans = max(SegmentTree::Ask(1, 1, n, x, x + c - 1).v, SegmentTree::Ask(1, 1, n, y - c + 1, y).v);
                if(ID[x] + 1 < ID[y]) {
                    ans = max(ans, Block.Ask(1, 1, B, ID[x] + 1, ID[y] - 1));
                    if(ID[x] + 1 < ID[y] - 1) ans = max(ans, Other.Ask(1, 1, B, ID[x] + 2, ID[y] - 1));
                    ans = max(ans, Tree[ID[x] + 1].Ask(1, 0, c, 0, R[ID[x]] - x + 1).ans);
                    ans = max(ans, Tree[ID[y]].Ask(1, 0, c, c - (y - L[ID[y]] + 1), c).ans);
                } else 
                    ans = max(ans, Tree[ID[y]].Ask(1, 0, c, R[ID[y]] - y + 1, R[ID[x]] - x + 1).ans);
                cout << ans << '\n';
            } else cout << SegmentTree::Ask(1, 1, n, x, y).v << '\n';
        }
    }

    return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 3ms
memory: 53512kb

input:

5 6 3
0 -5 -3 8 -3
2 3 5
1 2 5
2 1 5
1 4 -3
2 3 5
2 1 5

output:

8
10
0
5

result:

ok 4 number(s): "8 10 0 5"

Test #2:

score: -100
Wrong Answer
time: 718ms
memory: 141520kb

input:

200000 500000 1
387060158 961744470 37167782 737122872 -532977662 1604246 -30977399 871848791 444997246 454204578 -813187501 -660394286 448014171 -835115276 -631880452 887715308 258530352 805589560 -414653327 -156732249 -335096199 -80266237 367896009 738406627 -903652056 446120866 415658444 -1347916...

output:

999902477
1758325602
999343404
999847372
1288440931
998160312
1288440931
1758325602
1288440931
1758325602
1288440931
1758325602
1758325602
1758325602
1758325602
1288440931
1758325602
1758325602
1333916896
999723649
1758325602
999957587
1288440931
1758325602
1333916896
1758325602
1758325602
175832560...

result:

wrong answer 2nd numbers differ - expected: '999981999', found: '1758325602'