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\n", b[tmp.se]);
    }
    return 0;
}

/*
*/

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

时间: 2024-08-30 18:29:09

Codeforces 1000F One Occurrence 主席树|| 离线+线段树的相关文章

hdu 4638 Group(莫队算法|离线线段树)

Group Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1323    Accepted Submission(s): 703 Problem Description There are n men ,every man has an ID(1..n).their ID is unique. Whose ID is i and i-

CodeForces 52C Circular RMQ(区间循环线段树,区间更新,区间求和)

转载请注明出处:http://blog.csdn.net/u012860063 题目链接:http://codeforces.com/problemset/problem/52/C You are given circular array a0,?a1,?...,?an?-?1. There are two types of operations with it: inc(lf,?rg,?v) - this operation increases each element on the segm

HDU 4417 Super Mario(离线线段树or树状数组)

Problem Description Mario is world-famous plumber. His "burly" figure and amazing jumping ability reminded in our memory. Now the poor princess is in trouble again and Mario needs to save his lover. We regard the road to the boss's castle as a l

UPC 2224 Boring Counting (离线线段树,统计区间[l,r]之间大小在[A,B]中的数的个数)

题目链接:http://acm.upc.edu.cn/problem.php?id=2224 题意:给出n个数pi,和m个查询,每个查询给出l,r,a,b,让你求在区间l~r之间的pi的个数(A<=pi<=B,l<=i<=r). 参考链接:http://www.cnblogs.com/zj62/p/3558967.html #include <iostream> #include <cstdio> #include <cstring> #incl

codeforces 446C DZY Loves Fibonacci Numbers 数论+线段树成段更新

DZY Loves Fibonacci Numbers Time Limit:4000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u Submit Status Appoint description:  System Crawler  (2014-07-14) Description In mathematical terms, the sequence Fn of Fibonacci numbers is defi

27号的十道离线线段树

27号的十道离线线段树 hdu4288: (2012成都网络赛&&cf) #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 using namespace std; const

主席树/函数式线段树/可持久化线段树

什么是主席树 可持久化数据结构(Persistent data structure)就是利用函数式编程的思想使其支持询问历史版本.同时充分利用它们之间的共同数据来减少时间和空间消耗. 因此可持久化线段树也叫函数式线段树又叫主席树. 可持久化数据结构 在算法执行的过程中,会发现在更新一个动态集合时,需要维护其过去的版本.这样的集合称为是可持久的. 实现持久集合的一种方法时每当该集合被修改时,就将其整个的复制下来,但是这种方法会降低执行速度并占用过多的空间. 考虑一个持久集合S. 如图所示,对集合的

spoj gss2 : Can you answer these queries II 离线&amp;&amp;线段树

1557. Can you answer these queries II Problem code: GSS2 Being a completist and a simplist, kid Yang Zhe cannot solve but get Wrong Answer from most of the OI problems. And he refuse to write two program of same kind at all. So he always failes in co

HDU ACM 4417 Super Mario 离线线段树

分析:离线线段树,把所有询问离线读入,然后按H从小到大排序.对于所有结点也按从小到大排序,然后根据查询的H,将比H小的点加入到线段树,最后就是一个区间求和.这题貌似也可以用划分树,树状数组等方法做. #include<iostream> #include<algorithm> using namespace std; #define N 100005 struct Tree { int left,right,cnt; } TREE[N<<2]; struct Query