哥们我要崩溃了,求助求助
查看原帖
哥们我要崩溃了,求助求助
550957
Anonymely楼主2024/8/29 11:37
#include <bits/stdc++.h>
using namespace std;

/* --------------- fast io --------------- */ // begin
namespace Fread {
const int SIZE = 1 << 21;
char buf[SIZE], *S, *T;
inline char getchar() {
    if (S == T) {
        T = (S = buf) + fread(buf, 1, SIZE, stdin);
        if (S == T) return '\n';
    }
    return *S++;
}
} // namespace Fread
namespace Fwrite {
const int SIZE = 1 << 21;
char buf[SIZE], *S = buf, *T = buf + SIZE;
inline void flush() {
    fwrite(buf, 1, S - buf, stdout);
    S = buf;
}
inline void putchar(char c) {
    *S++ = c;
    if (S == T) flush();
}
struct NTR {
    ~ NTR() { flush(); }
} ztr;
} // namespace Fwrite
#ifdef ONLINE_JUDGE
#define getchar Fread :: getchar
#define putchar Fwrite :: putchar
#endif
namespace Fastio {
struct Reader {
    template<typename T>
    Reader& operator >> (T& x) {
        char c = getchar();
        T f = 1;
        while (c < '0' || c > '9') {
            if (c == '-') f = -1;
            c = getchar();
        }
        x = 0;
        while (c >= '0' && c <= '9') {
            x = x * 10 + (c - '0');
            c = getchar();
        }
        x *= f;
        return *this;
    }
    Reader& operator >> (char& c) {
        c = getchar();
        while (c == ' ' || c == '\n') c = getchar();
        return *this;
    }
    Reader& operator >> (char* str) {
        int len = 0;
        char c = getchar();
        while (c == ' ' || c == '\n') c = getchar();
        while (c != ' ' && c != '\n' && c != '\r') {
            str[len++] = c;
            c = getchar();
        }
        str[len] = '\0';
        return *this;
    }
    Reader(){}
} cin;
const char endl = '\n';
struct Writer {
    template<typename T>
    Writer& operator << (T x) {
        if (x == 0) { putchar('0'); return *this; }
        if (x < 0) { putchar('-'); x = -x; }
        static int sta[45];
        int top = 0;
        while (x) { sta[++top] = x % 10; x /= 10; }
        while (top) { putchar(sta[top] + '0'); --top; }
        return *this;
    }
    Writer& operator << (char c) {
        putchar(c);
        return *this;
    }
    Writer& operator << (char* str) {
        int cur = 0;
        while (str[cur]) putchar(str[cur++]);
        return *this;
    }
    Writer& operator << (const char* str) {
        int cur = 0;
        while (str[cur]) putchar(str[cur++]);
        return *this;
    }
    Writer(){}
} cout;
} // namespace Fastio
#define cin Fastio :: cin
#define cout Fastio :: cout
#define endl Fastio :: endl
/* --------------- fast io --------------- */ // end

#define QwQ01AwA return 0
#define ll long long
#define look_time cerr << 1.0 * clock() / CLOCKS_PER_SEC << '\n'
template <typename T> void ckmax(T &x, T y) {x = max(x, y);}
template <typename T> void ckmin(T &x, T y) {x = min(x, y);}
#define ull unsigned long long

const ll inf = 1e18;
const int N = 5e5 + 5;
int n, m;
namespace Seg {
    const int B = 16;
    const int lim = 8;
    struct Tree {
        int ls, rs, len;
        ll mn, mx, tag;
        ull sum;
        void clear() {
            ls = rs = len = 0;
            mn = mx = tag = 0;
            sum = 0;
        }
    } t[N << 5];
    #define ls t[p].ls
    #define rs t[p].rs
    int stk[N << 5], top, cnt;
    inline int newnode() {
        if (!top) return ++cnt;
        else return t[stk[top]].clear(), stk[top--];
    }
    ll a[N];
    int rt[114];
    ll L[114], R[114];
    inline int gid(ll x) {return x <= 0 ? 0 : (__lg(x) / 4 + 1);}
    inline void up(int p) {
        if (!ls) {
            t[p].mn = t[rs].mn;
            t[p].mx = t[rs].mx;
            t[p].len = t[rs].len;
            t[p].sum = t[rs].sum;
        } else if (!rs) {
            t[p].mn = t[ls].mn;
            t[p].mx = t[ls].mx;
            t[p].len = t[ls].len;
            t[p].sum = t[ls].sum;
        } else {
            t[p].mn = min(t[ls].mn, t[rs].mn);
            t[p].mx = max(t[ls].mx, t[rs].mx);
            t[p].len = t[ls].len + t[rs].len;
            t[p].sum = t[ls].sum + t[rs].sum;            
        }
    }
    inline void push(int p, ll w) {
        t[p].sum += 1ull * w * t[p].len;
        t[p].tag += w;
        t[p].mx += w, t[p].mn += w;
    }
    inline void down(int p) {
        if (!t[p].tag) return ;
        if (ls) push(ls, t[p].tag);
        if (rs) push(rs, t[p].tag);
        t[p].tag = 0;
    }
    inline bool chk(ll x, int i) {
        if (!i) return x <= 0;
        return gid(x) == i;
    }
    inline void rebuild(int p, int l, int r, int id) {
        t[p].mx = -2e9, t[p].mn = 2e9;
        t[p].len = t[p].tag = t[p].sum = 0;
        for (int i = l; i <= r; i++) {
            if (!chk(a[i], id)) continue;
            t[p].len++;
            ckmin(t[p].mn, a[i]);
            ckmax(t[p].mx, a[i]);
            t[p].sum += a[i];
        }
    }
    inline void ins(int &p, int l, int r, int x, int nid) {
        if (!p) p = newnode();
        if (r - l + 1 <= 32) {
            for (int i = l; i <= r; i++) {
                if (!chk(a[i], nid)) continue;
                a[i] += t[p].tag;
            }
            a[x] -= t[p].tag;
            t[p].tag = 0;
            rebuild(p, l, r, nid);
            return ;
        }
        int mid = (l + r) / 2; down(p);
        if (x <= mid) ins(ls, l, mid, x, nid);
        else ins(rs, mid + 1, r, x, nid);
        up(p);
    }   
    inline void upd(int &p, int l, int r, int L, int R, int x, int nid) {
        if (!p) return ;
        if (t[p].mn == x && t[p].mx == x) return ;
        if (r - l + 1 <= 32) {
            for (int i = l; i <= r; i++) {
                if (!chk(a[i], nid)) continue;
                a[i] += t[p].tag;
            }
            t[p].tag = 0;
            // ckmax(L, l), ckmin(R, r);
            int st = max(L, l), ed = min(R, r);
            for (int i = st; i <= ed; i++) {
                if (!chk(a[i], nid)) continue;
                if (a[i] == x) continue;
                a[i] -= x;
                if (nid && a[i] < Seg::L[nid]) {
                    if (a[i] <= 0) ins(rt[0], 1, n, i, 0);
                    else ins(rt[gid(a[i])], 1, n, i, gid(a[i]));
                }
            }
            rebuild(p, l, r, nid);
            return ;
        }
        if (L <= l && r <= R && (!nid || t[p].mn - x >= Seg::L[nid])) return push(p, -x);
        int mid = (l + r) / 2; down(p);
        if (L <= mid) upd(ls, l, mid, L, R, x, nid);
        if (mid < R) upd(rs, mid + 1, r, L, R, x, nid);
        up(p);
        if (!t[p].len) stk[++top] = p, p = 0;
    }
    ull query(int p, int l, int r, int L, int R, int nid) {
        if (!p) return 0;
        if (r - l + 1 <= 32) {
            for (int i = l; i <= r; i++) {
                if (!chk(a[i], nid)) continue;
                a[i] += t[p].tag;
            }
            t[p].tag = 0;
            // ckmax(L, l), ckmin(R, r);
            int st = max(L, l), ed = min(R, r);
            ull res = 0;
            for (int i = st; i <= ed; i++) {
                if (!chk(a[i], nid)) continue;
                res += a[i];
            }
            return res;
        }
        if (L <= l && r <= R) return t[p].sum;
        int mid = (l + r) / 2; down(p);
        ull res = 0;
        if (L <= mid) res += query(ls, l, mid, L, R, nid);
        if (mid < R) res += query(rs, mid + 1, r, L, R, nid);
        return res;
    }
    inline void init() {
        // t[0].clear();
        ll pw = 1;
        for (int i = 1; i <= lim; i++) {
            L[i] = pw;
            R[i] = 1ll * pw * B - 1;
            pw *= B;
        }
        for (int i = 1; i <= n; i++) {
            cin >> a[i];
            ins(rt[gid(a[i])], 1, n, i, gid(a[i]));
        }
    }
}

signed main() {
    // ios::sync_with_stdio(0);
    // cin.tie(0);
    cin >> n >> m;
    Seg::init();
    int lst = 0;
    while (m--) {
        int op;
        cin >> op;
        if (op == 1) {
            int l, r, x;
            cin >> l >> r >> x;
            l ^= lst, r ^= lst, x ^= lst;
            if (!x) continue;
            for (int i = 0; i <= Seg::lim; i++) Seg::upd(Seg::rt[i], 1, n, l, r, x, i);
        } else {
            int l, r;
            cin >> l >> r;
            l ^= lst, r ^= lst;
            ull ans = 0;
            for (int i = 0; i <= Seg::lim; i++) ans += Seg::query(Seg::rt[i], 1, n, l, r, i);
            lst = ans & ((1 << 20) - 1);
            cout << ans << endl;
        }
    }
    QwQ01AwA;
}

底层分块块长为 11 是对的,块长不为 11 就 WA55。

求和那里暴力递归到叶子节点也是对的。

2024/8/29 11:37
加载中...