3339: Rmq Problem

Time Limit: 20 Sec  Memory Limit: 128 MB
Submit: 1160  Solved: 596
[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

http://www.lydsy.com/JudgeOnline/problem.php?id=3339

思路:

首先,我们预处理处[1,i]区间中的mex函数,即mex[i]为(1~i)中没有出现过的数字。

然后对于区间的移动,从[l,r]->[l+1,r],我们定义next[l]表示下一次a[l]出现的位置。然后我们发现,如果next[l] >= r,那么区间[l,r]和[l+1,r]的sg函数是不一样的,所以,我们对于[ l+1,next[l]-1 ]区间进行修改操作,对mex取min的就好了。然后这步操作是区间操作,我们用线段树来解决就行。

然后我们开始从左到右暴力一遍,并且通过线段树来维护,lazy一下即可。

这题最关键的部分就是在于询问部分!

因为询问的话是询问一个区间[l,r]的,但是我们只需要询问第r个位置的mex的值是多少就好了。(因为线段树更新以后的[l+1, next[l] - 1 ]会对区间最小造成干扰,所以我们只需要知道在L之前,有没有一个区间能更新到R即可,所以就只需要查询R这个点)

//看看会不会爆int!数组会不会少了一维!
//取物问题一定要小心先手胜利的条件
#include <bits/stdc++.h>
using namespace std;
#pragma comment(linker,"/STACK:102400000,102400000")
#define LL long long
#define ALL(a) a.begin(), a.end()
#define pb push_back
#define mk make_pair
#define fi first
#define se second
#define haha printf("haha\n")
const int maxn = + ;
vector<pair<int, int> > ve[maxn];
int tree[maxn << ], lazy[maxn << ];
int n, q;
int a[maxn], mex[maxn];
bool vis[maxn];
int nxt[maxn], pos[maxn]; void build_tree(int l, int r, int o){
lazy[o] = -;
if (l == r){
tree[o] = mex[l]; return ;
}
int mid = (l + r) / ;
build_tree(l, mid, o << );
build_tree(mid + , r, o << | );
tree[o] = min(tree[o << ], tree[o << | ]);
} void push_down(int o){
int lb = o << , rb = o << | ;
if (lazy[lb] == - || lazy[lb] > lazy[o]){
lazy[lb] = lazy[o];
tree[lb] = min(tree[lb], lazy[lb]);
}
if (lazy[rb] == - || lazy[rb] > lazy[o]){
lazy[rb] = lazy[o];
tree[rb] = min(tree[rb], lazy[rb]);
}
tree[o] = -;
} int query(int x, int l, int r, int o){
if (x == l && x == r){
return tree[o];
}
if (lazy[o] != -) push_down(o);
int mid = (l + r) / ;
if (x <= mid) return query(x, l, mid, o << );
if (x > mid) return query(x, mid + , r, o << | );
} void update(int ql, int qr, int l, int r, int o, int val){
if (ql <= l && qr >= r){
if (lazy[o] == -) lazy[o] = val;
lazy[o] = min(lazy[o], val);
tree[o] = min(lazy[o], tree[o]);
return ;
}
if (lazy[o] != -)push_down(o);
int mid = (l + r) / ;
if (ql <= mid) update(ql, qr, l, mid, o << , val);
if (qr > mid) update(ql, qr, mid + , r, o << | , val);
tree[o] = min(tree[o << ], tree[o << | ]);
}
int ans[maxn];
void solve(){
build_tree(, n, );
for (int i = ; i <= n; i++){
for (int j = ; j < ve[i].size(); j++){
int pos = ve[i][j].fi, id = ve[i][j].se;
ans[id] = query(pos, , n, );
}
int lb = i + , rb = nxt[i] - ;
if (lb <= rb) update(lb, rb, , n, , a[i]);
}
for (int i = ; i <= q; i++){
printf("%d\n", ans[i]);
}
} int main(){
cin >> n >> q;
for (int i = ; i <= n; i++) {
scanf("%d", a + i);
vis[a[i]] = true;
mex[i] = mex[i - ];
while (vis[mex[i]]) mex[i]++;
pos[i] = n + ;
}
for (int i = ; i <= n; i++) pos[i] = n + ;
for (int i = n; i >= ; i--){
nxt[i] = pos[a[i]];
pos[a[i]] = i;
}
for (int i = ; i <= q; i++){
int l, r; scanf("%d%d", &l, &r);
ve[l].pb(mk(r, i));
}
solve();
return ;
}

维护后面的position sg函数概念,离线+线段 bzoj 3339的更多相关文章

  1. 维护后面的position + 离线 + 线段树 bzoj 3585

    3585: mex Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 918  Solved: 481[Submit][Status][Discuss] ...

  2. 【博弈论】【SG函数】【线段树】Petrozavodsk Summer Training Camp 2016 Day 9: AtCoder Japanese Problems Selection, Thursday, September 1, 2016 Problem H. Cups and Beans

    一开始有n个杯子,每个杯子里有一些豆子,两个人轮流操作,每次只能将一个豆子移动到其所在杯子之前的某个杯子里,不过可以移动到的范围只有一段区间.问你是否先手必胜. 一个杯子里的豆子全都等价的,因为sg函 ...

  3. 【主席树维护mex】 【SG函数递推】 Problem H. Cups and Beans 2017.8.11

    Problem H. Cups and Beans 2017.8.11 原题: There are N cups numbered 0 through N − 1. For each i(1 ≤ i ...

  4. 维护前面的position+主席树 Codeforces Round #406 (Div. 2) E

    http://codeforces.com/contest/787/problem/E 题目大意:给你n块,每个块都有一个颜色,定义一个k,表示在区间[l,r]中最多有k中不同的颜色.另k=1,2,3 ...

  5. js中的全局变量和静态变量的使用, js 的调试?- 如果js出错, js引擎 就会停止, 这会 导致 后面的 html中 refer 该函数时, 会报错 函数为定义!!

    效果里面的函数, 如show, hide,slideDown等, 这些都叫 "效果"函数, 但是里面可以包含动画, 也可以 不包含动画. 动画,是指 元素 的内容 是 逐渐 显示/ ...

  6. 解决绝对定位div position: absolute 后面的<a> Link不能点击

    今天布局的时候,遇到一个bug,当DIV设置为绝对定位时,这个div后面的相对定位的层里面的<a>Link标签无法点击. 网上的解决方案是在绝对定位层里面添加:pointer-events ...

  7. C++类的成员函数的形参列表后面的const

    看到(C++ Primer)类的成员函数这里,突然对成员函数形参列表后面的const感到迷惑. 因为书中开始说是修饰隐含形参this的,然后又说是声明该函数是只读的. 大为不解! 翻资料.找人讨论.. ...

  8. 【转】博弈问题及SG函数(真的很经典)

    博弈问题若你想仔细学习博弈论,我强烈推荐加利福尼亚大学的Thomas S. Ferguson教授精心撰写并免费提供的这份教材,它使我受益太多.(如果你的英文水平不足以阅读它,我只能说,恐怕你还没到需要 ...

  9. (转)博弈问题与SG函数

    博弈问题若你想仔细学习博弈论,我强烈推荐加利福尼亚大学的Thomas S. Ferguson教授精心撰写并免费提供的这份教材,它使我受益太多.(如果你的英文水平不足以阅读它,我只能说,恐怕你还没到需要 ...

随机推荐

  1. 王者荣耀交流协会 -- 第4次Scrum会议

    Scrum master : 王磊 要求1 : 工作照片 照片由高远博同学拍摄 ,王露芝同学(外援)没有参加本次会议. 要求2 : 时间跨度:2017年10月16日 18:00 - 18:44 共计4 ...

  2. c# 调用c++dll二次总结

    1.pinvoke结构不对称,添加语句(网上有) 2.含回调函数,成员参数的结构体必须完全,尽管自己用不到. 3.加深对c++指针的理解.一般情况下,类型加*等效于c++中的ref.但对于short* ...

  3. Codeforces Round #245 (Div. 1) B. Working out dp

    题目链接: http://codeforces.com/contest/429/problem/B B. Working out time limit per test2 secondsmemory ...

  4. 读我是一只it小小鸟有感!!!

    <<我是一只it小小鸟>>是老师为我们这些即将步入it行业的新人推荐的一本书,通过这本书的简介知道它是由一群it学子共同创造而成的,每个人分别讲述各自的成长经历.书的开篇是本书 ...

  5. selenium Object Page 设计模式理解及实现!

    Page Object模式是Selenium中的一种测试设计模式,主要是将每一个页面设计为一个Class,其中包含页面中需要测试的元素(按钮,输入框,标题 等),这样在Selenium测试页面中可以通 ...

  6. windows下面安装python3遇到的没有添加到环境变量的问题

    windows下面安装python3出现的问题 在官网上面下载最新版的安装包进行安装,并勾选Add Python 3.5 to PATH 安装的过程中可能会出现没有添加到PATH路径的情况 默认的安装 ...

  7. lock 默认公平锁还是非公平锁?公平锁是如何定义?如何实现

    ReentrantLock的实现是基于其内部类FairSync(公平锁)和NonFairSync(非公平锁)实现的. 其可重入性是基于Thread.currentThread()实现的: 如果当前线程 ...

  8. 【数据库】同一字段根据不同条件更新的sql语句的写法

    语法: update test set 字段1=case when 条件1 then 值1 when 条件2 then 值2 end 示例: update PMS_ProjectInfo set Pr ...

  9. bzoj1272 Gate Of Babylon(计数方法+Lucas定理+乘法逆元)

    Description Input Output Sample Input 2 1 10 13 3 Sample Output 12 Source 看到t很小,想到用容斥原理,推一下发现n种数中选m个 ...

  10. Android四大组件之Intent(续)