hdu4747——Mex
1、题目大意:对一个序列的每一个区间求Mex,最后所有的mex相加(mex就是SG的那个),力求nlogn。。。
2、分析:最近开始刷线段树了,还是有很多不会啊
首先把1-1 1-2 1-… 1-n这些区间的mex算出来,他一定是单调递增的,那么以2为左端点的区间,
他们的mex是可以用线段树做区间修改以1为左端点的区间的,比若说我们要修改以2为左端点的,
这个序列,下一次出现a[1]这个数的地方以后都没有影响,这是一定的
然后我们对于2到a[1]这些值所代表的区间mex值,我们就是要算qo = min(q[o], a[1]);
以为q[o]是单调的,所以我们可以二分,但是以为这道题是lazy所以二分的复杂度是log^2n,(因为要单点询问)
然而这会TLE
后来看了网上的kuangbin的blog里有这个的处理方法, 再维护一个区间最小值,然后写一个神奇的函数
这是一个递归函数,如果左儿子区间的RMQ
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
#define LL long long
struct segment_tree{
LL q[2000000];
LL m[2000000];
LL lazy[2000000];
LL x, y, z;
void add(LL l, LL r, LL o){
if(lazy[o] != -1){
lazy[2 * o] = lazy[o];
lazy[2 * o + 1] = lazy[o];
q[o] = (LL)lazy[o] * (r - l + 1);
m[o] = lazy[o];
lazy[o] = -1;
}
if(x > r || y < l) return;
if(x <= l && r <= y){
lazy[2 * o] = z;
lazy[2 * o + 1] = z;
q[o] = z * (r - l + 1);
m[o] = z;
return;
}
LL mid = (l + r) / 2;
add(l, mid, 2 * o);
add(mid + 1, r, 2 * o + 1);
q[o] = q[2 * o] + q[2 * o + 1];
m[o] = m[2 * o];
if(m[2 * o + 1] > m[o]) m[o] = m[2 * o + 1];
return;
}
LL query(LL l, LL r, LL o){
if(lazy[o] != -1){
lazy[2 * o] = lazy[o];
lazy[2 * o + 1] = lazy[o];
q[o] = (LL)lazy[o] * (r - l + 1);
m[o] = lazy[o];
lazy[o] = -1;
}
if(x > r || y < l) return 0;
if(x <= l && r <= y) return q[o];
LL mid = (l + r) / 2;
LL ret = 0;
ret += query(l, mid, 2 * o);
ret += query(mid + 1, r, 2 * o + 1);
q[o] = q[2 * o] + q[2 * o + 1];
m[o] = m[2 * o];
if(m[2 * o + 1] > m[o]) m[o] = m[2 * o + 1];
return ret;
}
LL get(LL l, LL r, LL o, LL u, LL st){
if(lazy[o] != -1){
lazy[2 * o] = lazy[o];
lazy[2 * o + 1] = lazy[o];
q[o] = (LL)lazy[o] * (r - l + 1);
m[o] = lazy[o];
lazy[o] = -1;
}
if(m[o] < u) return 0;
if(st == 1) return 0;
if(l == r) return l;
LL mid = (l + r) / 2;
LL ret = 1;
LL wl;
if(mid < x){
ret = 0;
wl = get(l, mid, 2 * o, u, 1);
}
else ret = get(l, mid, 2 * o, u, 0);
if(ret == 0) ret = get(mid + 1, r, 2 * o + 1, u, 0);
else wl = get(mid + 1, r, 2 * o + 1, u, 1);
q[o] = q[2 * o] + q[2 * o + 1];
m[o] = m[2 * o];
if(m[2 * o + 1] > m[o]) m[o] = m[2 * o + 1];
return ret;
}
} wt;
LL value[1000000];
bool vis[1000000];
LL head[1000000];
LL Next[1000000];
int main(){
LL n;
while(scanf("%I64d", &n) != EOF){
if(n == 0) return 0;
LL ans = 0;
wt.x = 1;
wt.y = n;
wt.z = 0;
wt.add(1, n, 1);
memset(vis, 0, sizeof(vis));
for(LL i = 0; i <= 300000; i ++) head[i] = n + 1;
for(LL i = 1; i <= n; i ++) scanf("%I64d", &value[i]);
LL o = 0;
for(LL i = 1; i <= n; i ++){
if(value[i] < n) vis[value[i]] = 1;
while(vis[o]) o ++;
wt.x = i; wt.y = i; wt.z = o;
wt.add(1, n, 1);
ans += o;
}
for(LL i = n; i >= 1; i --){
if(value[i] < n){
Next[i] = head[value[i]];
head[value[i]] = i;
}
}
for(LL i = 2; i <= n; i ++){
LL h = value[i - 1];
wt.x = i;
LL l = wt.get(1, n, 1, h, 0);
if(l <= Next[i - 1] - 1 && l != 0){
wt.x = l; wt.y = Next[i - 1] - 1; wt.z = h;
wt.add(1, n, 1);
}
wt.x = i; wt.y = n;
ans += wt.query(1, n, 1);
}
printf("%I64d\n", ans);
}
return 0;
}
hdu4747——Mex的更多相关文章
- HDU-4747 Mex(线段树区间更新)
题目大意:给一个长度为n的整数序列,定义mex(i,j)表示区间[i,j]中没有出现过的最小非负整数,求sigma(mex(i,j)),即序列中所有连续非空子区间的mex之和. 题目分析: answe ...
- HDU-4747 Mex 线段树
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4747 题意:求一个数列中,所有mex(L,R)的和. 注意到mex是单调不降的,那么首先预处理出mex ...
- [置顶] hdu4747 Mex 线段树
题意:给你一个序列,让你求出对于所有区间<i, j>的mex和,mex表示该区间没有出现过的最小的整数. 思路:从时限和点数就可以看出是线段树,并且我们可以枚举左端点i, 然后求出所有左端 ...
- [hdu4747]Mex
首先计算出以1为左端点的所有区间的mex,考虑删除左端点仍然维护这个序列:设当前删除点下一次出现在y,y~n的mex不变,从左端点到y的点中大于删除值的点要变成删除值,因为这个是不断递增的,所以是一段 ...
- HDU4747:Mex(线段树区间修改)
传送门 题意: 给出\(n\)个数,然后求\(\sum_{i=1}^n\sum_{j=i}^nmex(i,j)\).\(mex(i,j)\)表示区间\([i,j]\)的\(mex\). 思路: 考虑枚 ...
- Codeforces Round #381 (Div. 2)C. Alyona and mex(思维)
C. Alyona and mex Problem Description: Alyona's mother wants to present an array of n non-negative i ...
- Codeforces 740C. Alyona and mex 思路模拟
C. Alyona and mex time limit per test: 2 seconds memory limit per test: 256 megabytes input: standar ...
- bzoj3339 rmq problem (range mex query)
给一个长度为n的数列a,q个询问,每次询问一段区间的mex.(没有出现过的最小非负整数) 1<=n,q<=200000,0<=ai<=200000. 题解1 莫队 我们将权值分 ...
- 转:在VS2010下编译、调试和生成mex文件
最近帮人调了一个程序,是网上公开的代码,利用matlab与c++混合编程做三维模型关键点检测,发现他们可以用VS2010编译.调试.生成mexw32文件,因此觉得之前在Matlab上利用mex命令真是 ...
随机推荐
- Yocto开发笔记之《网卡配置》(QQ交流群:519230208)
QQ群:519230208,为避免广告骚扰,申请时请注明 “开发者” 字样 ============================================== # ifconfig -a # ...
- Java——按钮组件:JButton
import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import java.awt.Point; impor ...
- 有关stdint.h 文件
有关stdint.h 文件 Google C++编程规范的P25页有如下叙述: <stdint.h> 定义了 int16_t . uint32_t . int64_t 等整型,在需要确定大 ...
- php----显示中文乱码的问题
条件: 在显示页面设置页面编码格式为<?php header('Content-Type: text/html; charset=utf-8');?>: 在写入数据库时设置:mysql_q ...
- 微信H5手指滑动屏蔽微信的默认效果
我们的H5页面放在微信上时,如果你向上滑动或者向下滑动屏幕时,会发现一些微信的特征,譬如:网页由www.baidu.com提供. 去掉这个微信的特征,代码如下: var f; n.addEventLi ...
- bash: ifconfig: command not found解决方法
1.问题: #ifconfig bash: ifconfig: command not found 2.原因:非root用户的path中没有/sbin/ifconfig ,其它的命令也可以出现这种情况 ...
- Tomcat服务器原理详解
[目录]本文主要讲解Tomcat启动和部署webapp时的原理和过程,以及其使用的配置文件的详解.主要有三大部分: 第一部分.Tomcat的简介和启动过程 第二部分.Tomcat部署webapp 第三 ...
- Python之路【第四篇】:模块
什么是模块: 模块就是一个功能的集合. 模块就和乐高积木差不多,你用这些模块组合出一个模型,然后也可以用这个模块加上其他的模块组合成一个新的模型 模块的种类: 1.内置模块(python自带的比如os ...
- InstallShield 2010 使用 .net framework 4.5
一.InstallShield 2010 使用 .net framework 4.5记录 1.prq的地址,通过以下地址,下载相应的prq文件 .NET 4.5: http://saturn.inst ...
- Storm:最火的流式处理框架
伴随着信息科技日新月异的发展,信息呈现出爆发式的膨胀,人们获取信息的途径也更加多样.更加便捷,同时对于信息的时效性要求也越来越高.举个搜索场景中的例子,当一个卖家发布了一条宝贝信息时,他希望的当然是这 ...