Advanced Chairman tree

HDU-4348 To the moon

Description

You‘ve been given N integers A [1], A [2],..., A [N]. On these integers, you need to implement the following operations:
1. C l r d: Adding a constant d for every {A i | l <= i <= r}, and increase the time stamp by 1, this is the only operation that will cause the time stamp increase.
2. Q l r: Querying the current sum of {A i | l <= i <= r}.
3. H l r t: Querying a history sum of {A i | l <= i <= r} in time t.
4. B t: Back to time t. And once you decide return to a past, you can never be access to a forward edition anymore.
.. N, M ≤ 10 5, |A [i]| ≤ 10 9, 1 ≤ l ≤ r ≤ N, |d| ≤ 10 4 .. the system start from time 0, and the first modification is in time 1, t ≥ 0, and won't introduce you to a future state.

Input

n m
A 1 A 2 ... A n
... (here following the m operations. )

Output

... (for each query, simply print the result. )

Sample Input

10 5
1 2 3 4 5 6 7 8 9 10
Q 4 4
Q 1 10
Q 2 4
C 3 6 3
Q 2 4

2 4
0 0
C 1 1 1
C 2 2 -1
Q 1 2
H 1 2 1

Sample Output

4
55
9
15

0
1

answer

Chairman of the tree + mark permanent, if you add tags after each pushdown, for the President of the trees, the new node must each pushdown on a chain, if pushdown complexity of our space is not enough, so we need a permanent mark of at query time we record it marks starting from the root of a number, marked the answer every time statistics can contribute, rollback versions can be modified directly cnt is t 1 version of cnt +, because fallback after version can not return, can reduce space

Code

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int n, q;
const int N = 1e5 + 10;
ll a[N];
int L[N * 30], R[N * 30], T[N];
ll sum[N * 30];
ll addv[N * 30];
int cnt;
void pushup(int rt, int l, int r) {
    sum[rt] = sum[L[rt]] + sum[R[rt]] + addv[rt] * (r - l + 1);
}
int build(int l, int r) {
    int rt = ++cnt;
    if (l == r) {
        sum[rt] = a[l];
        return rt;
    }
    int mid = (l + r) >> 1;
    if (l < r) {
        L[rt] = build(l, mid);
        R[rt] = build(mid + 1, r);
    }
    pushup(rt, l, r);
    return rt;
}
int update(int pre, int l, int r, int ql, int qr, ll v) {
    int rt = ++cnt;
    int mid = (l + r) >> 1;
    L[rt] = L[pre], R[rt] = R[pre], sum[rt] = sum[pre], addv[rt] = addv[pre];
    if (ql <= l && r <= qr) {
        sum[rt] += (ll)(r - l + 1) * v;
        addv[rt] += v;
        return rt;
    }
    if (ql <= mid) L[rt] = update(L[pre], l, mid, ql, qr, v);
    if (qr > mid) R[rt] = update(R[pre], mid + 1, r, ql, qr, v);
    pushup(rt, l, r);
    return rt;
}
ll query(int rt, int l, int r, int ql, int qr, ll tot) {
    if (ql <= l && r <= qr) {
        return sum[rt] + tot * (r - l + 1);
    }
    tot += addv[rt];
    int mid = (l + r) >> 1;
    ll ans = 0;
    //pushdown(rt, l, r, L[rt], R[rt]);
    if (ql <= mid) ans += query(L[rt], l, mid, ql, qr, tot);
    if (qr > mid) ans += query(R[rt], mid + 1, r, ql ,qr, tot);
    return ans;
}
int main() {
    while (~scanf("%d%d", &n, &q)) {
        for (int i = 1; i <= n; i++) {
            scanf("%lld", &a[i]);
        }
        cnt = 0;
        memset(sum, 0, sizeof(sum));
        memset(addv, 0, sizeof(addv));
        T[0] = build(1, n);
        int now = 0;
        for (int i = 1; i <= q; i++) {
            char ch[2];
            int l, r; ll v;
            int t;
            scanf("%s", ch);
            if (ch[0] == 'Q') {
                scanf("%d%d", &l, &r);
                printf("%lld\n", query(T[now], 1, n, l, r, 0));
            }
            if (ch[0] == 'C') {
                scanf("%d%d%lld", &l, &r, &v);
                now++;
                T[now] = update(T[now - 1], 1, n, l, r, v);
            }
            if (ch[0] == 'H') {
                scanf("%d%d%d", &l, &r, &t);
                printf("%lld\n", query(T[t], 1, n, l, r, 0));
            }
            if (ch[0] == 'B') {
                scanf("%d", &t);
                now = t;
                cnt = T[now + 1];
            }
        }
    }
    return 0;
}

HDU-6278 Just \(h\)-index

Description

The \(h\)-index of an author is the largest \(h\) where he has at least \(h\) papers with citations not less than \(h\).

Bobo has published \(n\) papers with citations \(a_1, a_2, \dots, a_n\) respectively.
One day, he raises \(q\) questions. The \(i\)-th question is described by two integers \(l_i\) and \(r_i\), asking the \(h\)-index of Bobo if has only published papers with citations \(a_{l_i}, a_{l_i + 1}, \dots, a_{r_i}\).

Input

The input consists of several test cases and is terminated by end-of-file.

The first line of each test case contains two integers \(n\) and \(q\).
The second line contains \(n\) integers \(a_1, a_2, \dots, a_n\).
The \(i\)-th of last \(q\) lines contains two integers \(l_i\) and \(r_i\).

Output

For each question, print an integer which denotes the answer.

## Constraint

* \(1 \leq n, q \leq 10^5\)
* \(1 \leq a_i \leq n\)
* \(1 \leq l_i \leq r_i \leq n\)
* The sum of \(n\) does not exceed \(250,000\).
* The sum of \(q\) does not exceed \(250,000\).

Sample Input

5 3
1 5 3 2 1
1 3
2 4
1 5
5 1
1 2 3 4 5
1 5

Sample Output

2
2
2
3

answer

Dichotomous answers + Chairman trees, water problems

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int n, m;
const int N = 1e5 + 10;
int a[N];
int L[N * 20], R[N * 20], T[N];
int sum[N * 20];
int b[N];
int cnt;
int build(int l, int r) {
    int rt = ++cnt;
    sum[rt] = 0;
    int mid = (l + r) >> 1;
    if (l < r) {
        L[rt] = build(l, mid);
        R[rt] = build(mid + 1, r);
    }
    return rt;
}
int update(int pre, int l, int r, int x) {
    int rt = ++cnt;
    int mid = (l + r) >> 1;
    L[rt] = L[pre], R[rt] = R[pre], sum[rt] = sum[pre] + 1;
    if (l < r) {
        if (x <= mid) L[rt] = update(L[pre], l, mid, x);
        else R[rt] = update(R[pre], mid + 1, r, x);
    }
    return rt;
}
int query(int u, int v, int l, int r, int k) {
    if (l >= r) return l;
    int mid = (l + r) >> 1;
    int x = sum[L[v]] - sum[L[u]];
    if (x >= k) return query(L[u], L[v], l, mid, k);
    else return query(R[u], R[v], mid + 1, r, k - x);
}
int main() {
    while (~scanf("%d%d", &n, &m)) {
        cnt = 0;
        for (int i = 1; i <= n; i++) {
            scanf("%d", &a[i]);
            b[i] = a[i];
        }
        sort(b + 1, b + n + 1);
        int cnt1 = unique(b + 1, b + n + 1) - b - 1;
        T[0] = build(1, cnt1);
        for (int i = 1; i <= n; i++) {
            a[i] = lower_bound(b + 1, b + cnt1 + 1, a[i]) - b;
            T[i] = update(T[i - 1], 1, cnt1, a[i]);
        }
        while (m--) {
            int x, y;
            scanf("%d%d", &x, &y);
            int l = 1, r = y - x + 1;
            int ans = 0;
            while (l <= r) {
                int mid = (l + r) >> 1;
                if (b[query(T[x - 1], T[y], 1, cnt1, y - x + 2 - mid)] >= mid) {
                    ans = max(ans, mid);
                    l = mid + 1;
                }
                else r = mid - 1;
            }
            printf("%d\n", ans);
        }
    }
    return 0;
}

HDU-5919 Sequence II

Description

Mr. Frog has an integer sequence of length n, which can be denoted as \(a_1,a_2,\cdots ,a_n\) There are m queries.

In the i-th query, you are given two integers \(l_i\) and \(r_i\). Consider the subsequence $a_{l_i},a_{l_{i+1}},a_{l_{i+2}},\cdots ,a_{r_i} $.

We can denote the positions(the positions according to the original sequence) where an integer appears first in this subsequence as \(p_{1}^{(i)},p_{2}^{(i)},\cdots, p_{k_i}^{(i)}\) (in ascending order, i.e.,\(p_{1}^{(i)}<p_{2}^{(i)}<\cdots <p_{k_i}^{(i)}\)).

Note that \(k_i\) is the number of different integers in this subsequence. You should output \(p_{\left \lceil \frac{k_i}{2} \right \rceil}^{(i)}\)for the i-th query.

Input

In the first line of input, there is an integer T (\(T\leq 2\)) denoting the number of test cases.

Each test case starts with two integers n (\(n \leq 2 \times 10^5\)) and m (\(m\leq 2\times 10^5\)). There are n integers in the next line, which indicate the integers in the sequence(i.e., \(a_1,a_2,\cdots ,a_n, 0\leq a_i \leq 2 \times 10^5\)).

There are two integers \(l_i\) and \(r_i\) in the following m lines.

However, Mr. Frog thought that this problem was too young too simple so he became angry. He modified each query to \(l_i^`,r_i^`(1\leq l_i^` \leq n,1\leq r_i^` \leq n )\). As a result, the problem became more exciting.

We can denote the answers as \(ans_1, ans_2,\cdots ,ans_m\). Note that for each test case \(ans_0 = 0\).

You can get the correct input \(l_i,r_i\) from what you read (we denote them as \(l_i^`,r_i^`\))by the following formula:
\[ l_i = min\{ (l_i^`+ans_{i-1})\ mod \ n+1, (r_i^`+ans_{i-1})\ mod \ n+1 \} \]
\[ r_i = max\{ (l_i^`+ans_{i-1})\ mod \ n+1, (r_i^`+ans_{i-1})\ mod \ n+1 \} \]

Output

You should output one single line for each test case.

For each test case, output one line “Case #x: \(p_1,p_2,\cdots ,p_m\)”, where x is the case number (starting from 1) and \(p_1,p_2,\cdots ,p_m\) is the answer.

Sample Input

2
5 2
3 3 1 5 4
2 2
4 4
5 2
2 5 2 1 2
2 3
2 4

Sample Output

Case #1: 3 3
Case #2: 3 1

Hint

answer

The President tree inserted backwards, can count interval [l, r] of the number of species, the specific method is:

Maintaining a pos array, pos [a [i]] of the last recorded position of a [i] appears (is inserted upside down, i.e., the leftmost position), the President of the tree has no maintain each position number, rather than the number of Chairman of the tree is marked. When we insert a number, if pos [a [i]] == 0, z, at position i + 1 directly, or first pos [a [i]] -1 position, then the position i + 1, such interval endpoint \ (l \) corresponding to the Chairman of the tree maintains several numbers after l, we inquire how long it within a few [l, r], and then seek Fengyun tree after completing the first query \ ((sum + 1) / 2 \) large index how much can

Code

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int n, m;
const int N = 2e5 + 100;
int a[N];
int L[N * 40], R[N * 40], T[N];
int sum[N * 40];
int cnt;
int getnum() {
    int ans = 0; char c;
    while (!isdigit(c = getchar()));
    ans = c - '0';
    while (isdigit(c = getchar())) ans = ans * 10 + c - '0';
    return ans;
}
int build(int l, int r) {
    int rt = ++cnt;
    sum[rt] = 0;
    int mid = (l + r) >> 1;
    if (l < r) {
        L[rt] = build(l, mid);
        R[rt] = build(mid + 1, r);
    }
    return rt;
}
int update(int pre, int l, int r, int x, int v) {
    int rt = ++cnt;
    int mid = (l + r) >> 1;
    L[rt] = L[pre], R[rt] = R[pre], sum[rt] = sum[pre] + v;
    if (l < r) {
        if (x <= mid) L[rt] = update(L[pre], l, mid, x, v);
        else R[rt] = update(R[pre], mid + 1, r, x, v);
    }
    return rt;
}
int querysum(int rt, int l, int r, int ql, int qr) {
    if (ql <= l && r <= qr) {
        return sum[rt];
    }
    int mid = (l + r) >> 1;
    int ans = 0;
    if (ql <= mid) ans += querysum(L[rt], l, mid, ql, qr);
    if (qr > mid) ans += querysum(R[rt], mid + 1, r, ql, qr);
    return ans;
}
int queryk(int v, int l, int r, int k) {
    if (l >= r) return l;
    int mid = (l + r) >> 1;
    int x = sum[L[v]];
    if (x >= k) return queryk(L[v], l, mid, k);
    else return queryk(R[v], mid + 1, r, k - x);
}
int pos[N];
int main() {
    int t;
    t = getnum();
    int cse = 0;
    //freopen("ans.txt", "w", stdout);
    while (t--) {
        n = getnum(), m = getnum();
        cnt = 0;
        for (int i = 1; i <= n; i++) {
            a[i] = getnum();
        }
        T[n + 1] = build(1, n);
        memset(pos, 0, sizeof(pos));
        for (int i = n; i >= 1; i--) {
            if (!pos[a[i]]) {
                T[i] = update(T[i + 1], 1, n, i, 1);
                pos[a[i]] = i;
            }
            else {
                T[i] = update(T[i + 1], 1, n, i, 1);
                T[i] = update(T[i], 1, n, pos[a[i]], -1);
                pos[a[i]] = i;
            }
        }
        int ans = 0;
        cse++;
        printf("Case #%d:", cse);
        while (m--) {
            int l, r;
            l = getnum(), r = getnum();
            l = (l + ans) % n + 1;
            r = (r + ans) % n + 1;
            if (l > r) swap(l, r);
            int num = querysum(T[l], 1, n, l, r);
            printf(" %d", ans = queryk(T[l], 1, n, (num + 1) / 2));
        }
        printf("\n");
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/artoriax/p/11294800.html