简单题求助
查看原帖
简单题求助
1425622
违规用户名1425622楼主2024/9/22 18:35

我朋友写的代码被卡常了,求助,玄3关。

//P6578
#include <bits/stdc++.h>
#pragma target("avx512f,sse2,sse3,sse4,sse4.2")
#pragma optimize("Ofast")
using namespace std;

#define rg register
#define int unsigned
#define _f(i, a, b) for (rg int i = a; i <= b; ++i)
#define _d(i, a, b) for (rg int i = a; i >= b; --i)
typedef pair<int, int> pii;
typedef unsigned long long ll;
#define fi first
#define se second

namespace IO {
	static const int S = (1 << 23);
	char b[S], *m = b, *n = b, g[S], *p = g;
	void f() { fwrite(g, 1, p - g, stdout), p = g; }
	struct R {
		bool w(char c) { return 47 < c && c < 58; }
		char i() { if (m == n) n = (m = b) + fread(b, 1, S, stdin); return m == n ? ' ' : *m++; }
		template <class T> R &operator>>(T &x) { char c = i(); T f = 1; for (x = 0; !w(c);) { if(c == '-') f = -1; c = i(); } while (w(c)) x *= 10, x += c ^ 48, c = i(); x *= f; return *this; }
	} cin;
	struct W {
		void o(char c) { *p++ = c; if (p - g == S) f(); }
		template <class T> W &operator<<(T x) { if (!x) { o(48); return *this; } if(x < 0) o('-'), x = -x; int s[64], t = 0; while (x) s[++t] = x % 10, x /= 10; while (t) o(s[t--] + 48); return *this; }
		W &operator<<(char c) { o(c); return *this; }
		~W() { f(); }
	} cout;
} ;

#define cin IO::cin
#define cout IO::cout

static const int N = 3e5 + 5, S = 2048, T = 620, inf2 = 1e9;
static const ll inf = 1e18;

int n, m, a[N], tp, to[N], cntm, cntq;
ll ans[S], C[N];
bool vis[N], mask[N], use[N];
struct Block {
    int s, num, L[T], R[T], bel[N], len[T];
    void init(int n, int nn) {
        s = nn, num = (n / s) + !!(n % s);
        _f(i, 1, num) L[i] = R[i - 1] + 1, R[i] = R[i - 1] + s, len[i] = s;
        R[num] = n, len[num] = n - L[num] + 1;
        _f(i, 1, num) _f(j, L[i], R[i]) bel[j] = i;
    }
} arr, opt;
struct node {
    int pre, suf, len; ll ret;
    node() { pre = suf = len = ret = 0; }
    node (int x, int y, int l, ll r) { pre = x, suf = y, len = l, ret = r; }
} B[T];
inline node merge(node L, node R) {
    rg node ret;
    ret.len = L.len + R.len;
    ret.ret = L.ret + R.ret;
    if(L.suf && R.pre) ret.ret = ret.ret + C[L.suf + R.pre] - C[L.suf] - C[R.pre];
    ret.pre = L.pre, ret.suf = R.suf;
    if(L.pre == L.len) ret.pre += R.pre;
    if(R.suf == R.len) ret.suf += L.suf;
    return ret;
}
struct edge { int nxt, to; } e[N];
int ecnt, head[N];
inline void add(int x, int y) { e[++ecnt].to = y, e[ecnt].nxt = head[x], head[x] = ecnt; }
inline void insert(int x) {
    mask[x] = 1;
    rg int now = arr.bel[x];
    bool lft = (x != arr.L[now] && to[x - 1]), rgt = (x != arr.R[now] && to[x + 1]);
    if(lft && rgt) {
        B[now].ret += 1ll * (x - to[x - 1] + 1) * (to[x + 1] - x + 1);
        rg int tt = to[x - 1];
        to[tt] = to[x + 1], to[to[x + 1]] = tt;
    } else if(lft) B[now].ret += x - to[x - 1] + 1, to[x] = to[x - 1], to[to[x - 1]] = x;
    else if(rgt) B[now].ret += (to[x + 1] - x + 1), to[x] = to[x + 1], to[to[x + 1]] = x;
    else to[x] = x, B[now].ret++;
    if(mask[arr.L[now]]) B[now].pre = to[arr.L[now]] - arr.L[now] + 1;
    else B[now].pre = 0;
    if(mask[arr.R[now]]) B[now].suf = arr.R[now] - to[arr.R[now]] + 1;
    else B[now].suf = 0;
}
struct Roll {
    int id, pre, suf, now, t[4];
    ll ret;
} stk[S];
inline void ad(Roll &tmp, int k, int x) { tmp.t[k << 1] = x, tmp.t[k << 1 | 1] = to[x]; }
inline void insert2(int x) {
    int now = arr.bel[x];
    rg Roll tmp;
    tmp.ret = B[now].ret, tmp.id = x, mask[x] = 1, tmp.now = now;
    bool lft = (x != arr.L[now] && to[x - 1]), rgt = (x != arr.R[now] && to[x + 1]);
    if(lft && rgt) {
        B[now].ret += 1ll * (x - to[x - 1] + 1) * (to[x + 1] - x + 1);
        int tt = to[x - 1];
        ad(tmp, 0, tt), to[tt] = to[x + 1];
        ad(tmp, 1, to[x + 1]), to[to[x + 1]] = tt;
    } else if(lft) {
        B[now].ret += x - to[x - 1] + 1;
        ad(tmp, 0, x), to[x] = to[x - 1];
        ad(tmp, 1, to[x - 1]), to[to[x - 1]] = x;
    } else if(rgt) {
        B[now].ret += to[x + 1] - x + 1;
        ad(tmp, 0, x), to[x] = to[x + 1];
        ad(tmp, 1, to[x + 1]), to[to[x + 1]] = x;
    } else ad(tmp, 0, x), to[x] = x, B[now].ret++, ad(tmp, 1, 0);
    tmp.pre = B[now].pre, tmp.suf = B[now].suf;
    if(mask[arr.L[now]]) B[now].pre = to[arr.L[now]] - arr.L[now] + 1;
    else B[now].pre = 0;
    if(mask[arr.R[now]]) B[now].suf = arr.R[now] - to[arr.R[now]] + 1;
    else B[now].suf = 0;
    stk[++tp] = tmp;
}
inline void roll_back() {
    while(tp) {
        rg Roll tmp = stk[tp];
        to[tmp.t[2]] = tmp.t[3], to[tmp.t[0]] = tmp.t[1];
        B[tmp.now].pre = tmp.pre, B[tmp.now].suf = tmp.suf;
        mask[tmp.id] = 0, B[tmp.now].ret = tmp.ret;
        --tp;
    }
}
inline void clear() {
    _f(i, 1, arr.num) B[i].pre = B[i].suf = B[i].ret = 0;
    _f(i, 1, n) mask[i] = to[i] = 0;
}
inline node make_node(int l, int r) {
    rg int nowlen = 0, pre = inf2, suf = 0;
    rg ll ret = 0;
    _f(i, l, r) {
        if(mask[i]) ++nowlen;
        else {
            if(pre == inf2) pre = nowlen;
            ret += C[nowlen], nowlen = 0;
        }
    }
    if(mask[r]) {
        if(pre == inf2) pre = nowlen;
        ret += C[nowlen], suf = nowlen, nowlen = 0;
    }
    return node(pre, suf, r - l + 1, ret);
}
inline ll query(int l, int r) {
    if(arr.bel[l] == arr.bel[r]) return make_node(l, r).ret;
    rg node now = make_node(l, arr.R[arr.bel[l]]);
    _f(i, arr.bel[l] + 1, arr.bel[r] - 1) now = merge(now, B[i]);
    now = merge(now, make_node(arr.L[arr.bel[r]], r));
    return now.ret;
}
struct Modify { int pos, x, id; } p[S];
struct Query { int l, r, x, id, id2; } q[S];
inline bool cmp(Query x, Query y) { return x.x < y.x; }

signed main() {
// freopen("1.in", "r", stdin);
// freopen("1.out", "w", stdout);
    cin >> n >> m, arr.init(n, max((int)sqrt(0.8 * n), 1u)), opt.init(m, min((int)sqrt(11 * m), m));
    _f(i, 1, n) C[i] = 1ll * i * (i + 1) / 2, cin >> a[i];
    _f(i, 1, arr.num) B[i].len = arr.R[i] - arr.L[i] + 1;
    _f(i, 1, opt.num) {
        cntm = cntq = 0;
        _f(j, 1, opt.len[i]) {
            int op; cin >> op;
            if(op == 1) cin >> p[++cntm].pos >> p[cntm].x, p[cntm].id = j;
            else cin >> q[++cntq].l >> q[cntq].r >> q[cntq].x, q[cntq].id = j, q[cntq].id2 = cntq;
        }
        sort(q + 1, q + cntq + 1, cmp);
        int indl = 1;
        _f(j, 1, cntm) vis[p[j].pos] = 1;
        _f(j, 1, n) if(!vis[j]) add(a[j], j);
        _f(j, 1, cntq) {
            while(indl <= q[j].x) {
                for(int it = head[indl]; it; it = e[it].nxt) insert(e[it].to);
                ++indl;
            }
            _d(k, cntm, 1) if(p[k].id < q[j].id && !use[p[k].pos]) {
                use[p[k].pos] = 1;
                if(p[k].x <= q[j].x) insert2(p[k].pos);
            }
            _f(k, 1, cntm) if(!use[p[k].pos]) {
                use[p[k].pos] = 1;
                if(a[p[k].pos] <= q[j].x) insert2(p[k].pos);
            }
            ans[q[j].id2] = query(q[j].l, q[j].r), roll_back();
            _f(k, 1, cntm) use[p[k].pos] = 0;
        }
        _f(j, 1, cntq) cout << ans[j] << '\n'; 
        _f(j, 1, cntm) vis[p[j].pos] = 0, a[p[j].pos] = p[j].x;
        ecnt = 0, memset(head, 0, (n + 1) * sizeof(int));
        clear();
    }
// cerr << 1000 * clock() / CLOCKS_PER_SEC << '\n';
    return 0;
}

// by zzzcr.
2024/9/22 18:35
加载中...