Codeforces 1000F One Occurrence 主席树|| 离线+线段树

One Occurrence

为什么我半年前这么菜呀, 这种场只A三题。。。

我们在主席树 || 线段树上维护每个数的右边和它一样的数在哪里, 然后就变成了区间求最大值。

注意加进去的时候要把它右边一样的数的信息删掉。

我懒得离线数据就写了个主席树。

#include<bits/stdc++.h>
#define LL long long
#define fi first
#define se second
#define mk make_pair
#define PLL pair<LL, LL>
#define PLI pair<LL, int>
#define PII pair<int, int>
#define SZ(x) ((int)x.size())
#define ull unsigned long long

using namespace std;

const int N = 5e5 + 7;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + 7;
const double eps = 1e-8;
const double PI = acos(-1);

int n, cnt, rt[N], b[N];
int Map[N];

struct node {
    PII v;
    int ls, rs;
} a[N * 60];

void build(int l, int r, int& x) {
    x = ++cnt;
    if(l == r) {
        a[x].v = mk(0, l);
        return;
    }
    int mid = l + r >> 1;
    build(l, mid, a[x].ls);
    build(mid + 1, r, a[x].rs);
    a[x].v = max(a[a[x].ls].v, a[a[x].rs].v);
}

void update(int p, int val, int l, int r, int& x, int y) {
    x = ++cnt; a[x] = a[y];
    if(l == r) {
        a[x].v.fi = val;
        return;
    }
    int mid = l + r >> 1;
    if(p <= mid) update(p, val, l, mid, a[x].ls, a[y].ls);
    else update(p, val, mid + 1, r, a[x].rs, a[y].rs);
    a[x].v = max(a[a[x].ls].v, a[a[x].rs].v);
}

PII query(int L, int R, int l, int r, int x) {
    if(l >= L && r <= R) return a[x].v;
    int mid = l + r >> 1;
    if(R <= mid) return query(L, R, l, mid, a[x].ls);
    else if(L > mid) return query(L, R, mid + 1, r, a[x].rs);
    else return max(query(L, R, l, mid, a[x].ls), query(L, R, mid + 1, r, a[x].rs));
}

int main() {
    scanf("%d", &n);
    for(int i = 1; i <= n; i++) scanf("%d", &b[i]);
    for(int i = 1; i <= 500000; i++) Map[i] = n + 1;
    build(1, n, rt[n+1]);
    for(int i = n; i >= 1; i--) {
        update(i, Map[b[i]],  1, n, rt[i], rt[i + 1]);
        if(Map[b[i]] <= n) update(Map[b[i]], 0, 1, n, rt[i], rt[i]);
        Map[b[i]] = i;
    }
    int q; scanf("%d", &q);
    while(q--) {
        int L, R; scanf("%d%d", &L, &R);
        PII tmp = query(L, R, 1, n, rt[L]);
        if(tmp.fi <= R) puts("0");
        else printf("%d
", b[tmp.se]);
    }
    return 0;
}

/*
*/
原文地址:https://www.cnblogs.com/CJLHY/p/10436214.html