1 solutions
-
-1
就直接树套树维护一下就好了。
然后splay常数巨大,加上hfoj好像交不了C++20?所以挂了
#pragma GCC optmize("-Ofast,-inline,fast-math") #pragma GCC target("avx,sse,sse2,sse3,popcnt") #include <iostream> #include <cstdio> #include <algorithm> #include <cmath> #include <cstring> #include <string> #include <climits> #include <vector> using namespace std; const int N = 2e5 + 5; int h[N], n, m; vector<int> b; class Bit { public: int tr[N]; int lowbit(int x) { return x & -x; } void add(int x, int p) { while (x < N) { tr[x] += p; x += lowbit(x); } } int query(int x) { int res = 0; while (x) { res += tr[x]; x -= lowbit(x); } return res; } }tr; class Splay { public: struct Node { unsigned int son[2], fa, sz, cnt, val; }tr[N * 55]; unsigned int idx; unsigned int rubbish[N * 55], cnt = 0; #define gnode() (cnt ? rubbish[cnt--] : ++idx) void pushup(int u) { tr[u].sz = tr[tr[u].son[0]].sz + tr[tr[u].son[1]].sz + tr[u].cnt; } #define gt(x) ((x) == tr[tr[(x)].fa].son[1]) void rotate(int x) { int y = tr[x].fa, z = tr[y].fa; int chkx = gt(x), chky = gt(y); tr[y].son[chkx] = tr[x].son[chkx ^ 1]; if (tr[x].son[chkx ^ 1]) tr[tr[x].son[chkx ^ 1]].fa = y; tr[x].son[chkx ^ 1] = y; tr[y].fa = x; tr[x].fa = z; if (z) tr[z].son[chky] = x; pushup(y); pushup(x); } void splay(int u, int& rt) { for (int f = tr[u].fa; f = tr[u].fa, f; rotate(u)) { if (tr[f].fa) rotate(gt(f) == gt(u) ? f : u); } rt = u; } void ins(int x, int& rt) { if (!rt) { rt = gnode(); tr[rt].val = x; tr[rt].cnt = tr[rt].sz = 1; return; } int u = rt, f = 0, last = 0; while (true) { if (!u) { u = gnode(); tr[u].cnt = 1; tr[u].fa = f; tr[u].val = x; tr[f].son[last] = u; pushup(u); pushup(f); splay(u, rt); return; } if (tr[u].val == x) { tr[u].cnt++; pushup(u); pushup(f); splay(u, rt); return; } f = u; last = x > tr[u].val; u = tr[u].son[last]; } } int get_rank(int x, int &rt) { int res = 0, u = rt; while (true) { //if (!u) return 0; if (tr[u].val > x) { u = tr[u].son[0]; } else if (tr[u].val == x) { res += tr[tr[u].son[0]].sz; splay(u, rt); return res + 1; } else { res += tr[tr[u].son[0]].sz + tr[u].cnt; u = tr[u].son[1]; } } } int pre(int& rt) { unsigned int u = tr[rt].son[0]; while (tr[u].son[1]) u = tr[u].son[1]; splay(u, rt); return tr[u].val; } void CLEAR(int u) { tr[u].cnt = tr[u].fa = tr[u].son[0] = tr[u].son[1] = tr[u].sz = tr[u].val = 0; rubbish[++cnt] = u; } void del(int x, int& rt) { //printf("ok\n"); get_rank(x, rt); //printf("!!!\n"); int u = rt; if (tr[u].cnt > 1) { tr[u].cnt--; pushup(u); return; } if (!tr[u].son[0]) { rt = tr[u].son[1]; tr[rt].fa = 0; CLEAR(u); return; } if (!tr[u].son[1]) { rt = tr[u].son[0]; tr[rt].fa = 0; CLEAR(u); return; } pre(rt); tr[rt].son[1] = tr[u].son[1]; tr[tr[u].son[1]].fa = rt; pushup(rt); CLEAR(u); } }; class SegmentTree { public: Splay s; struct Node { int l, r, rt; }tr[N << 2]; void build(int u, int l, int r, int* a) { tr[u] = { l, r, 0 }; for (int i = l; i <= r; i++) { s.ins(a[i], tr[u].rt); } if (l == r) return; int mid = l + r >> 1; build(u << 1, l, mid, a); build(u << 1 | 1, mid + 1, r, a); } int getrank(int u, int l, int r, int k) { if (tr[u].l >= l and tr[u].r <= r) { //printf("ok0\n"); s.ins(k, tr[u].rt); int p = s.get_rank(k, tr[u].rt) - 1; s.del(k, tr[u].rt); return p; } int mid = tr[u].l + tr[u].r >> 1, res = 0; if (l <= mid) res = getrank(u << 1, l, r, k); if (r > mid) res += getrank(u << 1 | 1, l, r, k); return res; } void update(int u, int v, int x, int p) { s.del(p, tr[u].rt); s.ins(x, tr[u].rt); if (tr[u].l == tr[u].r) return; int mid = tr[u].l + tr[u].r >> 1; if (v <= mid) update(u << 1, v, x, p); else update(u << 1 | 1, v, x, p); } }trs; int main() { scanf("%d%d", &n, &m); for (int i = 1; i <= n; i++) { h[i] = i; } long long res = 0LL; for (int i = n; i >= 1; i--) { res += tr.query(h[i] - 1); tr.add(h[i], 1); } trs.build(1, 1, n, h); while (m--) { int x, y; scanf("%d%d", &x, &y); if (x > y) swap(x, y); if (x == y - 1) { res -= (h[x] > h[y]); res += (h[y] > h[x]); swap(h[x], h[y]); trs.update(1, x, h[x], h[y]); trs.update(1, y, h[y], h[x]); } else { res -= trs.getrank(1, x + 1, y - 1, h[x]); res += (y - 1 - x) - trs.getrank(1, x + 1, y - 1, h[x] + 1); res -= (y - 1 - x) - trs.getrank(1, x + 1, y - 1, h[y] + 1); res += trs.getrank(1, x + 1, y - 1, h[y]); res -= 1LL * (h[x] > h[y]); res += 1LL * (h[y] > h[x]); swap(h[x], h[y]); trs.update(1, x, h[x], h[y]); trs.update(1, y, h[y], h[x]); } printf("%lld\n", res); } return 0; }
- 1
Information
- ID
- 6315
- Time
- 4000ms
- Memory
- 512MiB
- Difficulty
- 8
- Tags
- # Submissions
- 7
- Accepted
- 1
- Uploaded By