bzoj 3339: Rmq Problem

3339: Rmq Problem

Time Limit: 20 Sec  Memory Limit: 128 MB
Submit: 1270  Solved: 666
[Submit][Status][Discuss]

Description

Input

Output

Sample Input

7 5
0 2 1 0 1 3 2
1 3
2 3
1 4
3 6
2 7

Sample Output

3
0
3
2
4

HINT

Source

By Xhr

嗯,莫队

懒得敲线段树,毕竟线段树比较短

#include<cmath>
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn = 200006;
int sz,block[maxn];
struct Que{
    int l,r,id;
    bool operator < (const Que&a)const
    {
        return block[l]==block[a.l] ? r<a.r : l<a.l;
    }
}q[maxn];
int a[maxn],n,m,tmp,have[maxn],ans[maxn];int l=1,r=0;
void add(int x)
{
    ++have[x];
    if(x==tmp||!x)while(have[tmp])++tmp;
}
void del(int x)
{
    --have[x];
    if(x < tmp&&!have[x])tmp=x;
}
void md(int &l,int &r,int ql,int qr,int id)
{
    while(r < qr)add(a[++r]);
    while(r > qr)del(a[r--]);
    while(l < ql)del(a[l++]);
    while(l > ql)add(a[--l]);
    ans[id]=tmp;
}
int main()
{
    scanf("%d%d",&n,&m);
    sz=sqrt(n);
    for(int i=1;i<=n;i++)
        scanf("%d",a+i),block[i]=(i-1)/sz+1;
    for(int i=1;i<=m;i++)
        scanf("%d%d",&q[i].l,&q[i].r),q[i].id=i;
    sort(q+1,q+m+1);
    for(int i=1;i<=m;++i) md(l,r,q[i].l,q[i].r,q[i].id);
    for(int i=1;i<=m;i++)printf("%d\n",ans[i]);
    return 0;

}
时间: 2024-08-09 21:58:58

bzoj 3339: Rmq Problem的相关文章

BZOJ - 3339: Rmq BZOJ - 3585: mex

3339: Rmq Problem 3585: mex 题解:分块维护权值,用莫队转移. 分块修改操作$O(1)$,查询$O(\sqrt{A_{max}})$.莫队转移$O(m\sqrt n)$.总共是$O(m\sqrt n)$ 一份代码解决两道题.额外的经验! 1 #include<cmath> 2 #include<algorithm> 3 #include<cstdio> 4 #include<iostream> 5 using namespace s

【BZOJ】3339: Rmq Problem &amp; 3585: mex(线段树+特殊的技巧)

http://www.lydsy.com/JudgeOnline/problem.php?id=3585 好神的题. 但是!!!!!!!!!!!!!!我线段树现在要开8倍空间才能过!!!!!!!!!!这什么梗...................... 我思考了很久空间的问题,因为我在pushdown的时候可能会越界,或许是pushup? 不管了.然后看了zyf的写法.看来以后得注意下...pushdown弄成先放了... 本题的做法: 好神orz 首先像莫队一样离线区间,左端点在前. 考虑如何

bzoj 3585: mex &amp;&amp; 3339: Rmq Problem -- 主席树

3585: mex Time Limit: 20 Sec  Memory Limit: 128 MB Description 有一个长度为n的数组{a1,a2,...,an}.m次询问,每次询问一个区间内最小没有出现过的自然数. Input 第一行n,m. 第二行为n个数. 从第三行开始,每行一个询问l,r. Output 一行一个数,表示每个询问的答案. Sample Input 5 5 2 1 0 2 1 3 3 2 3 2 4 1 2 3 5 Sample Output 1 2 3 0 3

【BZOJ】【3339】Rmq Problem

离线+线段树 Orz Hzwer,引用题解: 这一题在线似乎比较麻烦 至于离线.. 首先按照左端点将询问排序 然后一般可以这样考虑 首先如何得到1-i的sg值呢 这个可以一开始扫一遍完成 接着考虑l-r和l+1-r的答案有何不同 显然是l-next[l]-1这一段所有sg值大于a[l]的变为a[l] 这一步如果暴力修改的话只有30分 但是修改区间我们可以想到线段树,这样就能a了 晚上写题有点晕……忘了把当前时刻now置为q[i].l了,这种傻逼错误居然也犯…… 1 /**************

Rmq Problem

大视野——3339: Rmq Problem Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 1192  Solved: 620[Submit][Status][Discuss] Description Input Output Sample Input 7 50 2 1 0 1 3 21 32 31 43 62 7 Sample Output 30324 HINT Source By Xhr 思路: 对于这个题似乎暴力不好打,而且似乎强制在线操作

【BZOJ】【3489】A simple rmq problem

KD-Tree(乱搞) Orz zyf教给蒟蒻做法 蒟蒻并不会这题正解……(可持久化树套树?...Orz 对于每个点,我们可以求出pre[i],nex[i],那么询问的答案就是:求max (a[i]),其中 i 满足$ ( pre[i]<ql \ and \ nex[i]>qr\ and\ i \in [ql,qr] ) $ 然后我们以(i,pre[i],nex[i])为坐标……将所有点抽象到三维空间中,每次查询就相当于是一次区域求最值! 这题我的感受: 因为前面做了两道区域求和的……然后思路

【BZOJ3489】A simple rmq problem kd-tree

[BZOJ3489]A simple rmq problem Description 因为是OJ上的题,就简单点好了.给出一个长度为n的序列,给出M个询问:在[l,r]之间找到一个在这个区间里只出现过一次的数,并且要求找的这个数尽可能大.如果找不到这样的数,则直接输出0.我会采取一些措施强制在线. Input 第一行为两个整数N,M.M是询问数,N是序列的长度(N<=100000,M<=200000) 第二行为N个整数,描述这个序列{ai},其中所有1<=ai<=N 再下面M行,每

【bzoj3339】Rmq Problem

[bzoj3339]Rmq Problem Description Input Output Sample Input 7 50 2 1 0 1 3 21 32 31 43 62 7 Sample Output 30324 HINT 分析 离线算法. 对于[l,r]区间的询问,我们可以线性求出来,然后考虑[l+1,r]区间有什么不同,在a[l]下一次出现的位置之前,所有大于a[l]的mex,都变成是a[l],因为 [l+1,a[l]下一次出现的位置-1],这个区间内没有a[l]了,大于它的数当然

AC日记——Periodic RMQ Problem codeforces 803G

G - Periodic RMQ Problem 思路: 题目给一段序列,然后序列复制很多次: 维护序列很多次后的性质: 线段树动态开点: 来,上代码: #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define maxn 100005 struct TreeNodeType { int l, r, mid