我朋友写的代码被卡常了,求助,玄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.