TIOJ-1739

[APIO ‘08] Beads [Interactive]

https://tioj.ck.tp.edu.tw/problems/1739

Description

有一個長度$n$的序列$a$,一開始$a_i = i$
接下來有$m$個操作,每個操作只會交換相鄰的兩個數字
接著有$q$個詢問,每次會詢問:第$t$個操作之後,數字$x$被放到哪個位置?
$n,m,q \leq 3 \times 10^5; 1 \leq x \leq n; 1 \leq t \leq m$

Solution

對序列保存不同的版本,當然持久化資料結構砸下去就對啦
是說本來想寫treap不過我實作能力好差QQ
什麼?你想問什麼是持久化?
反正就是用樹來存一個序列啦,然後因為改一個數字時只要改他到根的那條鏈就好了啦,這樣每次修改新增的點數會和樹高一樣

AC code

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
//   __________________
//  | ________________ |
//  ||          ____  ||
//  ||   /\    |      ||
//  ||  /__\   |      ||
//  || /    \  |____  ||
//  ||________________||
//  |__________________|
//  \###################\
//   \###################\
//    \        ____       \
//     \_______\___\_______\
// An AC a day keeps the doctor away.

#pragma g++ optimize("Ofast")
#pragma loop_opt(on)
#include <bits/stdc++.h>
#ifdef local
#define debug(x) (cerr<<#x<<" = "<<(x)<<'\n')
#else
#define debug(x) ((void)0)
#endif // local

using namespace std;
typedef int64_t ll;
constexpr ll N = 300025, K = 64;
#include "lib1739.h"

struct segtree {
    struct node {
        int l,r,val;
    } S[N*K];
    int tot;
    int newnode(int v) {
        return S[++tot] = {0,0,v}, tot;
    }
    int newnode(int l,int r) {
        return S[++tot] = {l,r,0}, tot;
    }
    int build(int l, int r) {
        if(l+1 == r) return newnode(l);
        int m = l+(r-l>>1);
        return newnode(build(l,m),build(m,r));
    }
    int modify(int root, int p, int k, int l, int r) {
        if(l+1 == r) return newnode(k);
        int m = l+(r-l>>1);
        if(p < m)
            return newnode(modify(S[root].l,p,k,l,m), S[root].r);
        else
            return newnode(S[root].l, modify(S[root].r,p,k,m,r));
    }
    int query(int root, int p, int l, int r) {
        while(l+1 < r) {
            int m = l+(r-l>>1);
            if(p < m) r = m, root = S[root].l;
            else l = m, root = S[root].r;
        }
        return S[root].val;
    }
} sgt;
int n,m;
int root[N],chg[N],v[N],pos[N];
void init() {
    root[0] = sgt.build(1,n+1);
    for(int i = 1; i <= n; i++) v[i] = pos[i] = i;
    for(int i = 1; i <= m; i++) {
        int a = chg[i], b = chg[i]+1;
        int r = sgt.modify(root[i-1],v[a],pos[v[b]],1,n+1);
        root[i] = sgt.modify(r,v[b],pos[v[a]],1,n+1);
        swap(pos[v[a]], pos[v[b]]);
        swap(v[a], v[b]);
    }
}
signed main() {
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= m; i++) scanf("%d", chg+i);
    init();
    int q = getNumQuestions();
    while(q--) {
        int A,B;
        getQuestion(A, B);
        answer(sgt.query(root[B],A,1,n+1));
    }
}
comments powered by Disqus