传送门

这个题的方法好像很多啊

1.莫队暴力

2.线段树 + 离线处理

先预处理出sg[i]表示前i个数的sg值,next[i]表示i的下一位置在哪里,如果后面再没有i,那么next[i] = n + 1

然后把线段树的每个叶子节点放上sg[i]。

把询问按照左端点由小到大排序,我们考虑如何从 l ~ r 转移到 l + 1 ~ r,

会发现,当把a[l]这个数去掉之后,如果后面没有a[l]那么答案就可能会更新,

那么我们可以更新 l + 1 ~ next[l] - 1这个区间,也就是用线段树操作

#include <cstdio>
#include <iostream>
#include <algorithm>
#define N 200001
#define INF ~(1 << 31)
#define root 1, 1, n
#define ls now << 1, l, mid
#define rs now << 1 | 1, mid + 1, r
#define min(x, y) ((x) < (y) ? (x) : (y)) int n, q;
int a[N], next[N], vis[N], ans[N], mx[N << 2], sg[N]; struct node
{
int x, y, id;
}p[N]; inline int read()
{
int x = 0, f = 1;
char ch = getchar();
for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -1;
for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - '0';
return x * f;
} inline bool cmp(node x, node y)
{
return x.x < y.x;
} inline void build(int now, int l, int r)
{
if(l == r)
{
mx[now] = sg[l];
return;
}
mx[now] = INF;
int mid = (l + r) >> 1;
build(ls);
build(rs);
} inline void push_down(int now)
{
if(mx[now] != INF)
{
mx[now << 1] = min(mx[now << 1], mx[now]);
mx[now << 1 | 1] = min(mx[now << 1 | 1], mx[now]);
mx[now] = INF;
}
} inline void update(int now, int l, int r, int x, int y, int d)
{
if(x <= l && r <= y)
{
mx[now] = min(mx[now], d);
return;
}
push_down(now);
int mid = (l + r) >> 1;
if(x <= mid) update(ls, x, y, d);
if(mid < y) update(rs, x, y, d);
} inline int query(int now, int l, int r, int x)
{
if(l == r) return mx[now];
push_down(now);
int mid = (l + r) >> 1;
if(x <= mid) return query(ls, x);
else return query(rs, x);
} int main()
{
int i, j = 0, now = 1, nxt;
n = read();
q = read();
for(i = 1; i <= n; i++) a[i] = read();
for(i = 1; i <= n; i++)
{
vis[a[i]] = 1;
while(vis[j]) j++;
sg[i] = j;
}
build(root);
for(i = 0; i <= n; i++) vis[i] = n + 1;
for(i = n; i >= 1; i--) next[i] = vis[a[i]], vis[a[i]] = i;
for(i = 1; i <= q; i++)
{
p[i].id = i;
p[i].x = read();
p[i].y = read();
}
std::sort(p + 1, p + q + 1, cmp);
for(i = 1; i <= q; i++)
{
while(now < p[i].x)
{
if(now + 1 < next[now])
update(root, now + 1, next[now] - 1, a[now]);
now++;
}
ans[p[i].id] = query(root, p[i].y);
}
for(i = 1; i <= q; i++) printf("%d\n", ans[i]);
return 0;
}

3.主席树

。。不会

[BZOJ3339] Rmq Problem(线段树)的更多相关文章

  1. Codeforces 803G Periodic RMQ Problem 线段树

    Periodic RMQ Problem 动态开点线段树直接搞, 我把它分成两部分, 一部分是原来树上的, 一部分是后来染上去的,两个部分取最小值. 感觉有点难写.. #include<bits ...

  2. bzoj 3489 A simple rmq problem - 线段树

    Description 因为是OJ上的题,就简单点好了.给出一个长度为n的序列,给出M个询问:在[l,r]之间找到一个在这个区间里只出现过一次的数,并且要求找的这个数尽可能大.如果找不到这样的数,则直 ...

  3. [bzoj3339]Rmq Problem||[bzoj3585]mex_线段树

    Rmq Problem bzoj-3339||mex bzoj-3585 题目大意:给定一个长度为n的数列a,多次讯问区间l,r中最小的不属于集合{$A_l,A_{l+1}...A_r$}的非负整数. ...

  4. bzoj 3489 A simple rmq problem——主席树套线段树

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3489 题解:http://www.itdaan.com/blog/2017/11/24/9b ...

  5. 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 Sa ...

  6. bzoj 3489: A simple rmq problem k-d树思想大暴力

    3489: A simple rmq problem Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 551  Solved: 170[Submit][ ...

  7. Codeforces Round #271 (Div. 2) F. Ant colony (RMQ or 线段树)

    题目链接:http://codeforces.com/contest/474/problem/F 题意简而言之就是问你区间l到r之间有多少个数能整除区间内除了这个数的其他的数,然后区间长度减去数的个数 ...

  8. 【题解】BZOJ3489 A Hard RMQ problem(主席树套主席树)

    [题解]A simple RMQ problem 占坑,免得咕咕咕了,争取在2h内写出代码 upd:由于博主太菜而且硬是要用指针写两个主席树,所以延后2hQAQ upd:由于博主太菜而且太懒所以他决定 ...

  9. Uva 12299 带循环移动的RMQ(线段树)

    题目链接:https://vjudge.net/contest/147973#problem/C 题意:传统的RMQ是一个不变的数组a求区间最值.现在要循环移动(往前移动). 分析:求区间问题,很容易 ...

随机推荐

  1. uvm_marcos——UVM宏定义

    I programmed all night.Through the window, on my screen,The rising sun shined. 编程一整夜,透过窗户,照在屏幕上.初升的太 ...

  2. Invalid bound statement (not found): com.ros.dao.LogMapper.insert

    org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.ros.dao.LogMapp ...

  3. Data truncation: Data too long for column 'id' at row 1

    Caused by: java.sql.BatchUpdateException: Data truncation: Data too long for column 'titleimg' at ro ...

  4. OpenCV2:总结篇 core模块

    一.cv::Mat 1.作用 cv::Mat表示图像类,用来操作图像和矩阵,它包含很多属性和方法 2.构造方法 cv::Mat image;  //cv::Mat image()      无参数构造 ...

  5. SniperOJ-leak-x86-64

    参考:1.借助DynELF实现无libc的漏洞利用小结 2.一步一步学ROP之linux_x64篇 - 蒸米 题目源码 #include <stdio.h> #include <un ...

  6. javaEE(12)_数据库连接池

    一.直接获取数据库连接和通过池获取示意图: 二.编写数据库连接池 1.实现DataSource接口,并实现连接池功能的步骤: •在DataSource构造函数中批量创建与数据库的连接,并把创建的连接加 ...

  7. fopen()和socket()的内在联系

    int portone=socket(AF_INET,SOCK_STREAM, 0); printf("portone=%d",portone); printf("ope ...

  8. UVa-101-木块问题

    这题用vector比较好写,我们设置对应的几个函数,然后进行相应的操作来简化代码,这样才不易出错. 对于输入和操作来说我们经分析之后,可以看到最后一个操作时最原始的操作也就是不需要还原任意一个堆任意高 ...

  9. [LUOGU] 3959 宝藏

    https://www.luogu.org/problemnew/show/P3959 注意到n非常小,考虑状压/搜索. 发现状压需要枚举起点,跑n次,一个问题是转移不可以以数字大小为阶段了,考虑用d ...

  10. Linux运维发展与学习路线图

    记录一下Linux所要懂的知识体系,方便未来学习的时候自我验证. Linux运维课程体系大纲: Linux入门 了解Linux基础,知道什么是Linux,会安装Linux,使用相关基础命令,如:cd, ...