【bzoj3339】Rmq Problem

【bzoj3339】Rmq Problem

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

分析

离线算法。

对于[l,r]区间的询问,我们可以线性求出来,然后考虑[l+1,r]区间有什么不同,在a[l]下一次出现的位置之前,所有大于a[l]的mex,都变成是a[l],因为 [l+1,a[l]下一次出现的位置-1],这个区间内没有a[l]了,大于它的数当然可以是它。

所以将询问的先按左端点排序,然后递增左端点,不断更新,用线段树维护。

code

  1 #include<cstdio>
  2 #include<algorithm>
  3 #define lson l,m,rt<<1
  4 #define rson m+1,r,rt<<1|1
  5
  6 using namespace std;
  7
  8 const int MAXN = 200100;
  9 const int INF = 1e9;
 10
 11 struct Que{
 12     int l,r,id;
 13     bool operator < (const Que &x) const
 14     {
 15         return l < x.l;
 16     }
 17 }q[MAXN];
 18 int a[MAXN],sg[MAXN],mn[MAXN<<2];
 19 int next[MAXN],last[MAXN],ans[MAXN];
 20 bool vis[MAXN];
 21 int n,m,k = 0,now;
 22
 23 int read()
 24 {
 25     int x=0;char ch=getchar();
 26     while(ch<‘0‘||ch>‘9‘) {ch=getchar(); }
 27     while(ch>=‘0‘&&ch<=‘9‘) {x=x*10+ch-‘0‘; ch=getchar(); }
 28     return x;
 29 }
 30 void pushdown(int rt)
 31 {
 32     if (mn[rt]!=INF)
 33     {
 34         mn[rt<<1] = min(mn[rt],mn[rt<<1]);
 35         mn[rt<<1|1] = min(mn[rt],mn[rt<<1|1]);
 36     }
 37 }
 38 void build(int l,int r,int rt)
 39 {
 40     mn[rt] = INF;
 41     if (l==r)
 42     {
 43         mn[rt] = sg[l];
 44         return ;
 45     }
 46     int m = (l+r)>>1;
 47     build(lson);
 48     build(rson);
 49 }
 50 void update(int l,int r,int rt,int L,int R,int v)
 51 {
 52     if (L<=l&&r<=R)
 53     {
 54         mn[rt] = min(mn[rt],v);
 55         return ;
 56     }
 57     pushdown(rt);
 58     int m = (l+r)>>1;
 59     if (L<=m) update(lson,L,R,v);
 60     if (R>m)  update(rson,L,R,v);
 61 }
 62 int query(int l,int r,int rt,int p)
 63 {
 64     if (l==r) return mn[rt];
 65     pushdown(rt);
 66     int m = (l+r)>>1;
 67     if (p<=m) return query(lson,p);
 68     else return query(rson,p);
 69 }
 70
 71 int main()
 72 {
 73     n = read();m = read();
 74     for (int i=1; i<=n; ++i)
 75         a[i] = read();
 76     for (int i=1;i<=m; ++i)
 77         q[i].l = read(), q[i].r = read(), q[i].id = i;
 78     sort(q+1,q+m+1);
 79     for (int i=1; i<=n; ++i)
 80     {
 81         vis[a[i]] = true;
 82         while (vis[k]) k++;
 83         sg[i] = k;
 84     }
 85     build(1,n,1);
 86     for (int i=n; i; --i)
 87         next[i] = last[a[i]], last[a[i]] = i;
 88     now = 1;
 89
 90     for (int i=1; i<=m; ++i)
 91     {
 92         while (now<q[i].l)
 93         {
 94             if (!next[now]) next[now] = n+1;
 95             update(1,n,1,now,next[now]-1,a[now]);
 96             now++;
 97         }
 98         ans[q[i].id] = query(1,n,1,q[i].r);
 99     }
100     for (int i=1; i<=m; ++i)
101         printf("%d\n",ans[i]);
102     return 0;
103 }

(……)

时间: 2024-10-03 20:04:10

【bzoj3339】Rmq Problem的相关文章

【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 /**************

【luogu4137】 Rmq Problem / mex - 莫队

题目描述 有一个长度为n的数组{a1,a2,…,an}.m次询问,每次询问一个区间内最小没有出现过的自然数. 输入输出格式 输入格式: 第一行n,m. 第二行为n个数. 从第三行开始,每行一个询问l,r. 输出格式: 一行一个数,表示每个询问的答案. 思路 莫队算法详见『这里』 其实这题也不是莫队 a高达10^9,只能说是 数据水2333333333 #include <bits/stdc++.h> using namespace std; const int maxn = 200000 +

【BZOJ4999】This Problem Is Too Simple! 离线+树状数组+LCA

[BZOJ4999]This Problem Is Too Simple! Description 给您一颗树,每个节点有个初始值. 现在支持以下两种操作: 1. C i x(0<=x<2^31) 表示将i节点的值改为x. 2. Q i j x(0<=x<2^31) 表示询问i节点到j节点的路径上有多少个值为x的节点. Input 第一行有两个整数N,Q(1 ≤N≤ 100,000:1 ≤Q≤ 200,000),分别表示节点个数和操作个数. 下面一行N个整数,表示初始时每个节点的初

【BZOJ2298】[HAOI2011]problem a DP

[BZOJ2298][HAOI2011]problem a Description 一次考试共有n个人参加,第i个人说:“有ai个人分数比我高,bi个人分数比我低.”问最少有几个人没有说真话(可能有相同的分数) Input 第一行一个整数n,接下来n行每行两个整数,第i+1行的两个整数分别代表ai.bi Output 一个整数,表示最少有几个人说谎 Sample Input 3 2 0 0 2 2 2 Sample Output 1 HINT 100%的数据满足: 1≤n≤100000   0≤

【数论】X problem

X problem      X问题     Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)    Total Submission(s): 4358 Accepted Submission(s): 1399 Problem Description 求在小于等于N的正整数中有多少个X满足:X mod a[0] = b[0], X mod a[1] = b[1], X mod a[2]

【算法】RMQ LCA 讲课杂记

4月4日,应学弟要求去了次学校讲了一堂课,其实讲的挺内容挺杂的,但是目的是引出LCA算法. 现在整理一下当天讲课的主要内容: 开始并没有直接引出LCA问题,而是讲了RMQ(Range Minimum/Maximum Query)问题. RMQ指的是对于给定的一个数组,每一次询问一个区间[L,R]中数字的最小或最大值,一个很经典的问题. 一开始没有学生知道如何求解此问题.我将问题弱化,每一次询问[1,R]中数字的最值,有学生打出了求一个min/max数组即可,此为正解. 这是一个相当正确的做法,有

【倍增】RMQ的ST表算法

RMQ问题:给定一个长度为N的区间,M个询问,每次询问Li到Ri这段区间元素的最大值/最小值. RMQ的高级写法一般有两种,即为线段树和ST表. 本文主要讲解一下ST表的写法.(以区间最大值为例) ST表:一种利用dp求解区间最值的倍增算法. 定义:f[i][j]表示i到i+2^j-1这段区间的最大值. 预处理:f[i][0]=a[i].即i到i区间的最大值就是a[i]. 状态转移:将f[i][j]平均分成两段,一段为f[i][j-1],另一段为f[i+2^(j-1)][j-1]. 两段的长度均

BZOJ3339:Rmq Problem &amp; BZOJ3585 &amp; 洛谷4137:mex——题解

前者:https://www.lydsy.com/JudgeOnline/problem.php?id=3339 后者: https://www.lydsy.com/JudgeOnline/problem.php?id=3585 https://www.luogu.org/problemnew/show/P4137 有一个长度为n的数组{a1,a2,…,an}.m次询问,每次询问一个区间内最小没有出现过的自然数. 题解大部分都是莫队分块,但是复杂度为O(n*sqrt(n))=5e2*2e5=1e

【水】TJU Problem 1805 Electrical Outlets

没看懂题,直接看了INPUT,原来真的可以猜出来. 原题: 1805.   Electrical Outlets Time Limit: 1.0 Seconds   Memory Limit: 65536KTotal Runs: 3321   Accepted Runs: 2575 Roy has just moved into a new apartment. Well, actually the apartment itself is not very new, even dating ba