请各位巨佬分析一下两份代码,以及为何代码2快

P1253 扶苏的问题

cyj20080401 @ 2024-12-14 14:13:15

代码2是AI优化的代码1 1.

#include<iostream>
#include<vector>
using namespace std;
typedef long long ll;
typedef vector<ll> vll;
const ll INF = 1e18;
inline int read() {
    int x = 0, f = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9') {
        if (ch == '-') f = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9') {
        x = x * 10 + ch - '0';
        ch = getchar();
    }
    return x * f;
}
struct SegmentTree {
    vll maxx, setv, addv;
    int n;

   inline bool in(int l, int r, int x, int y) {
        return l >= x && r <= y;
    }

   inline bool out(int l, int r, int x, int y) {
        return l > y || r < x;
    }

    void pushup(int u) {
        maxx[u] = max(maxx[u << 1], maxx[(u << 1) | 1]);
    }

    void maketag(int u, int type, ll x) {
        if (type == 1) {
            maxx[u] = x;
            setv[u] = x;
            addv[u] = 0;
        }
        else {
            if (setv[u] == INF) {
                maxx[u] += x;
                addv[u] += x;
            }
            else {
                setv[u] += x;
                maxx[u] = setv[u];
            }
        }
    }

    void pushdown(int node) {
        if(setv[node]!= INF||addv[node]){
        if (setv[node]!= INF) {
            maketag(node << 1, 1, setv[node]);
            maketag((node << 1) | 1, 1, setv[node]);
            setv[node] = INF;
        }
        if (addv[node]) {
            maketag(node << 1, 2, addv[node]);
            maketag((node << 1) | 1, 2, addv[node]);
            addv[node] = 0;
        }
        }
    }

    void update(int u, int l, int r, int x, int y, int type, ll val) {
        if (in(l, r, x, y)) {
            maketag(u, type, val);
            return;
        }
        pushdown(u);
        int mid = (l + r) >> 1;
        if (!out(l, mid, x, y)) update(u << 1, l, mid, x, y, type, val);
        if (!out(mid + 1, r, x, y)) update((u << 1) | 1, mid + 1, r, x, y, type, val);
        pushup(u);
    }

    ll query(int u, int l, int r, int x, int y) {
        if (in(l, r, x, y)) return maxx[u];
        if (out(l, r, x, y)) return -INF;
        pushdown(u);
        int mid = (l + r) >> 1;
        return max(query(u << 1, l, mid, x, y), query((u << 1) | 1, mid + 1, r, x, y));
    }

    void build(vll arr, int u, int l, int r) {
        if (l == r) {
            maxx[u] = arr[l];
            return;
        }
        int mid = (l + r) >> 1;
        build(arr, u << 1, l, mid);
        build(arr, (u << 1) | 1, mid + 1, r);
        pushup(u);
    }

    SegmentTree(vll arr, int m) : n(m) {
        maxx.resize(4 * m);
        setv.resize(4 * m);
        addv.resize(4 * m);
        build(arr, 1, 1, n);
        fill(setv.begin(), setv.end(), INF);
    }
};

int main() {
    int n = read(), q = read();
    vll arr(n + 1);
    for (int i = 1; i <= n; ++i)
        arr[i] = read();
    SegmentTree tree(arr, n);
    int op, l, r;
    ll x;
    while (q--) {
        op = read();
        l = read();
        r = read();
        if (op == 3)
            printf("%lld\n", tree.query(1, 1, n, l, r));
        else {
            x = read();
            tree.update(1, 1, n, l, r, op, x);
        }
    }
    return 0;
}

2.

#include<iostream>
#include<vector> 
using namespace std;
typedef long long ll;
typedef vector<ll> vll;
const ll INF = 1e18;
inline int read() {
    int x = 0, f = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9') {
        if (ch == '-') f = -1;
        ch = getchar();
    }
    do {
        x = x * 10 + ch - '0';
        ch = getchar();
    } while (ch >= '0' && ch <= '9');
    return x * f;
}

struct SegmentTree {
    vll maxx, setv, addv;
    int n;
    inline bool in(int l, int r, int x, int y) {
        return l >= x && r <= y;
    }

    inline bool out(int l, int r, int x, int y) {
        return l > y || r < x;
    }

    void pushup(int u) {
        maxx[u] = max(maxx[u << 1], maxx[(u << 1) | 1]);
    }

    void maketag(int u, int type, ll x) {
        if (type == 1) {
            maxx[u] = x;
            setv[u] = x;
            addv[u] = 0;
        }
        else {
            if (setv[u] == INF) {
                maxx[u] += x;
                addv[u] += x;
            }
            else {
                setv[u] += x;
                maxx[u] = setv[u];
            }
        }
    }

    // 优化后的pushdown函数
    void pushdown(int node) {
        if (setv[node]!= INF || addv[node]) {
            if (setv[node]!= INF) {
                maketag(node << 1, 1, setv[node]);
                maketag((node << 1) | 1, 1, setv[node]);
                setv[node] = INF;
            }
            if (addv[node]) {
                maketag(node << 1, 2, addv[node]);
                maketag((node << 1) | 1, 2, addv[node]);
                addv[node] = 0;
            }
        }
    }

    void update(int u, int l, int r, int x, int y, int type, ll val) {
        if (in(l, r, x, y)) {
            maketag(u, type, val);
            return;
        }
        pushdown(u);
        int mid = (l + r) >> 1;
        if (!out(l, mid, x, y)) update(u << 1, l, mid, x, y, type, val);
        if (!out(mid + 1, r, x, y)) update((u << 1) | 1, mid + 1, r, x, y, type, val);
        pushup(u);
    }

    ll query(int u, int l, int r, int x, int y) {
        if (in(l, r, x, y)) return maxx[u];
        if (out(l, r, x, y)) return -INF;
        pushdown(u);
        int mid = (l + r) >> 1;
        return max(query(u << 1, l, mid, x, y), query((u << 1) | 1, mid + 1, r, x, y));
    }

    // 优化后的build函数
    void build(vll& arr, int u, int l, int r) {
        maxx[u] = arr[l];
        if (l < r) {
            int mid = (l + r) >> 1;
            build(arr, u << 1, l, mid);
            build(arr, (u << 1) | 1, mid + 1, r);
            pushup(u);
        }
    }

    SegmentTree(vll arr, int m) : n(m) {
        int totalNodes = 4 * m;
        maxx.resize(totalNodes);
        setv.resize(totalNodes);
        addv.resize(totalNodes);
        build(arr, 1, 1, n);
        std::fill(setv.begin(), setv.end(), INF);
    }
};

int main() {
    int n = read(), q = read();
    vll arr(n + 1);
    for (int i = 1; i <= n; ++i)
        arr[i] = read();
    SegmentTree tree(arr, n);
    int op, l, r;
    ll x;
    while (q--) {
        op = read();
        l = read();
        r = read();
        if (op == 3)
            printf("%lld\n", tree.query(1, 1, n, l, r));
        else {
            x = read();
            tree.update(1, 1, n, l, r, op, x);
        }
    }
    return 0;
}

谢谢各位


by MinLand @ 2024-12-15 10:16:47

AI给你做了一下更改

  1. 快读改成了 do while显然不会优化
  2. pushdown()帮你格式化了一下,显然没有用。
  3. build()函数改成了引用,其余的没有提升

总结一下,唯一的提升在于build在使用的时候改成了引用,不引用会导致整个vector被复制一遍,导致额外的时间消耗。


|