1 条题解

  • 1
    @ 2025-1-18 14:48:30
    #include <bits/stdc++.h>
    
    #define i64 long long int
    
    #define pii pair<int, int>
    #define mp make_pair
    #define fi first
    #define se second
    
    #define eb emplace_back
    
    using namespace std;
    
    inline int Read() 
    {
        int res;
        return scanf("%d", &res), res;
    }
    inline i64 Read64() 
    {
        i64 res;
        return scanf("%lld", &res), res;
    }
    
    const int INF_32 = 1e9;
    const i64 INF_64 = 1e18;
    
    const int N = 50000 + 5, M = 5000000 + 5;
    
    int n, q, a[N];
    
    mt19937 Rng((unsigned)time(NULL));
    
    int ls[M], rs[M], val[M], key[M], sz[M], tot = 0;
    
    struct FHQ 
    {
        int rt = 0;
        void Update(int u) 
        {
            sz[u] = sz[ls[u]] + sz[rs[u]] + 1;
        }
    
        void Split(int u, int x, int &L, int &R) 
        {
            if (!u)
                return L = R = 0, void();
    
            if (val[u] <= x)
                L = u, Split(rs[u], x, rs[L], R);
            else
                R = u, Split(ls[u], x, L, ls[R]);
    
            Update(u);
        }
    
        int Merge(int L, int R) 
        {
            if (!L || !R)
                return L + R;
    
            if (key[L] > key[R]) 
            {
                rs[L] = Merge(rs[L], R);
                return Update(L), L;
            } 
            else 
            {
                ls[R] = Merge(L, ls[R]);
                return Update(R), R;
            }
        }
    
        int NewNode(int x) 
        {
            key[++ tot] = Rng(), val[tot] = x, sz[tot] = 1;
            ls[tot] = rs[tot] = 0;
            return tot;
        }
    
        void Insert(int x) 
        {
            int L, R;
            Split(rt, x, L, R);
            rt = Merge(Merge(L, NewNode(x)), R);
        }
    
        void Erase(int x) 
        {
            int L, R, t1, t2;
            Split(rt, x, L, R);
            Split(L, x - 1, t1, t2);
            t2 = Merge(ls[t2], rs[t2]);
            rt = Merge(Merge(t1, t2), R);
        }
    
        int Rank(int u, int k) 
        {
            if (!u)
                return 0;
    
            return val[u] < k ? sz[ls[u]] + 1 + Rank(rs[u], k) : Rank(ls[u], k);
        }
    
        int Kth(int u, int k) 
        {
            if (k == sz[ls[u]] + 1)
                return val[u];
    
            return k <= sz[ls[u]] ? Kth(ls[u], k) : Kth(rs[u], k - 1 - sz[ls[u]]);
        }
    } tr[N << 2];
    
    void Build(int id, int l, int r) 
    {
        for (int i = l; i <= r; ++ i)
            tr[id].Insert(a[i]);
    
        if (l < r) 
        {
            int mid = (l + r) >> 1;
            Build(id << 1, l, mid), Build(id << 1 | 1, mid + 1, r);
        }
    }
    
    void Change(int id, int l, int r, int x, int y) 
    {
        tr[id].Erase(a[x]), tr[id].Insert(y);
    
        if (l == r)
            return ;
    
        int mid = (l + r) >> 1;
    
        if (x <= mid)
            Change(id << 1, l, mid, x, y);
        else
            Change(id << 1 | 1, mid + 1, r, x, y);
    }
    
    int GetRank(int id, int l, int r, int L, int R, int x) 
    {
        if (L <= l && r <= R)
            return tr[id].Rank(tr[id].rt, x);
    
        int mid = (l + r) >> 1, ans = 0;
    
        if (L <= mid)
            ans += GetRank(id << 1, l, mid, L, R, x);
    
        if (R > mid)
            ans += GetRank(id << 1 | 1, mid + 1, r, L, R, x);
    
        return ans;
    }
    
    int Kth(int L, int R, int x) 
    {
        if (x < 0)
            return -2147483647;
    
        if (x > R - L + 1)
            return 2147483647;
    
        int l = 0, r = 100000000, mid, res = 2147483647;
    
        while (l <= r) 
        {
            mid = (l + r) >> 1;
    
            if (GetRank(1, 1, n, L, R, mid) <= x)
                res = mid, l = mid + 1;
            else
                r = mid - 1;
        }
    
        return res;
    }
    
    int main() 
    {
        n = Read(), q = Read();
    
        for (int i = 1; i <= n; ++ i)
            a[i] = Read();
    
        Build(1, 1, n);
    
        while (q --) 
        {
            int opt = Read();
    
            if (opt == 1) 
            {
                int l = Read(), r = Read(), k = Read();
                printf("%d\n", GetRank(1, 1, n, l, r, k) + 1);
            }
    
            if (opt == 2) 
            {
                int l = Read(), r = Read(), k = Read() - 1;
                printf("%d\n", Kth(l, r, k));
            }
    
            if (opt == 3) 
            {
                int pos = Read(), k = Read();
                Change(1, 1, n, pos, k), a[pos] = k;
            }
    
            if (opt == 4) 
            {
                int l = Read(), r = Read(), k = Read();
                printf("%d\n", Kth(l, r, GetRank(1, 1, n, l, r, k) - 1));
            }
    
            if (opt == 5) 
            {
                int l = Read(), r = Read(), k = Read();
                printf("%d\n", Kth(l, r, GetRank(1, 1, n, l, r, k + 1)));
            }
        }
    
        return 0;
    }
    
    
    • 1

    信息

    ID
    5537
    时间
    3000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者