3339: Rmq Problem

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

[Submit][Status][Discuss]

题解:

3585和3339貌似除了范围不一样,好像重了。。。

但是我想了一种只能过3339的方法。。。(3585也可以过的>_<,具体往下看!!!)

*增加:因为我们询问的区间在1~n内,所以权值大于n的一定不是mex,所以不用修改,直接跳过。(可以在纸上画画)*

*于是就可以A两道了~~~*

莫队+树状数组+二分。。。

莫队和树状数组是毫无疑问要用的。。。

但是二分呢???

我们考虑如何能算一个原序列的mex???

就是对于一个区间,我们用树状数组来维护其中出现过的元素。出现过的标记为1,没有的标记为0。若一个区间内的1的个数等于区间的长度,则mex一定不存在于此区间内。若1的个数小于区间长度,则一定存在于此区间内。

例如:

0 1 2 3

—  ——  > 代表0,2,3被选了

1 0 1 1  --->  把存在的标记为1。

——  > 二分的前一半和为1,但长度为2,所以一定存在mex。

剩余的继续二分。(程序下面还有东西的!!!)

 #include<bits/stdc++.h>
using namespace std;
#define MAXN 200010
struct node
{
int l,r,id;
}q[MAXN];
int tot,BIT[MAXN],color[MAXN],sz[MAXN],pos[MAXN],ans[MAXN],gs[MAXN];
int read()
{
int s=,fh=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')fh=-;ch=getchar();}
while(ch>=''&&ch<=''){s=s*+(ch-'');ch=getchar();}
return s*fh;
}
bool cmp(node aa,node bb)
{
if(pos[aa.l]==pos[bb.l])return aa.r<bb.r;
return aa.l<bb.l;
}
int Lowbit(int o){return o&(-o);}
void Update(int o,int o1)
{
while(o<=tot)
{
BIT[o]+=o1;
o+=Lowbit(o);
}
}
int Sum(int o)
{
int sum=;
while(o>)
{
sum+=BIT[o];
o-=Lowbit(o);
}
return sum;
}
int getans(int L,int R)
{
int mid,wz;
if(Sum(R)-Sum(L-)==(L-R+))return R+;
while(L<=R)
{
int mid=(L+R)/;
if((Sum(mid)-Sum(L-))<(mid-L+))wz=mid,R=mid-;
else L=mid+;
}
return wz;
}
int main()
{
int n,m,block,i,L,R,wz;
n=read();m=read();
block=(int)sqrt(n);
for(i=;i<=n;i++)color[i]=read(),sz[i]=color[i];
sort(sz+,sz+n+);
tot=unique(sz+,sz+n+)-(sz+);
for(i=;i<=m;i++)q[i].l=read(),q[i].r=read(),q[i].id=i;
for(i=;i<=n;i++)pos[i]=(int)(i-)/block+,color[i]++;
sort(q+,q+m+,cmp);
L=;R=;
memset(gs,,sizeof(gs));
for(i=;i<=m;i++)
{
while(L<q[i].l)
{
//wz=lower_bound(sz+1,sz+tot+1,color[L])-sz;
wz=color[L];
gs[wz]--;
if(gs[wz]==)Update(wz,-);
L++;
}
while(L>q[i].l)
{
L--;
//wz=lower_bound(sz+1,sz+tot+1,color[L])-sz;
wz=color[L];
gs[wz]++;
if(gs[wz]==)Update(wz,);
}
while(R<q[i].r)
{
R++;
//wz=lower_bound(sz+1,sz+tot+1,color[R])-sz;
wz=color[R];
gs[wz]++;
if(gs[wz]==)Update(wz,);
}
while(R>q[i].r)
{
//wz=lower_bound(sz+1,sz+tot+1,color[R])-sz;
wz=color[R];
gs[wz]--;
if(gs[wz]==)Update(wz,-);
R--;
}
ans[q[i].id]=getans(,n+);
}
for(i=;i<=m;i++)printf("%d\n",ans[i]-);
fclose(stdin);
fclose(stdout);
return ;
}

两道题都可以过的程序:

 #include<bits/stdc++.h>
using namespace std;
#define MAXN 200010
struct node
{
int l,r,id;
}q[MAXN];
int tot,BIT[MAXN],color[MAXN],sz[MAXN],pos[MAXN],ans[MAXN],gs[MAXN];
int read()
{
int s=,fh=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')fh=-;ch=getchar();}
while(ch>=''&&ch<=''){s=s*+(ch-'');ch=getchar();}
return s*fh;
}
bool cmp(node aa,node bb)
{
if(pos[aa.l]==pos[bb.l])return aa.r<bb.r;
return aa.l<bb.l;
}
int Lowbit(int o){return o&(-o);}
void Update(int o,int o1)
{
while(o<=tot)
{
BIT[o]+=o1;
o+=Lowbit(o);
}
}
int Sum(int o)
{
int sum=;
while(o>)
{
sum+=BIT[o];
o-=Lowbit(o);
}
return sum;
}
int getans(int L,int R)
{
int mid,wz;
if(Sum(R)-Sum(L-)==(L-R+))return R+;
while(L<=R)
{
int mid=(L+R)/;
if((Sum(mid)-Sum(L-))<(mid-L+))wz=mid,R=mid-;
else L=mid+;
}
return wz;
}
int main()
{
int n,m,block,i,L,R,wz;
n=read();m=read();
block=(int)sqrt(n);
for(i=;i<=n;i++)color[i]=read(),sz[i]=color[i];
sort(sz+,sz+n+);
tot=unique(sz+,sz+n+)-(sz+);
for(i=;i<=m;i++)q[i].l=read(),q[i].r=read(),q[i].id=i;
for(i=;i<=n;i++)pos[i]=(int)(i-)/block+,color[i]++;
sort(q+,q+m+,cmp);
L=;R=;
memset(gs,,sizeof(gs));
for(i=;i<=m;i++)
{
while(L<q[i].l)
{
//wz=lower_bound(sz+1,sz+tot+1,color[L])-sz;
wz=color[L];
if(wz<=n+)//加这一句就可以过了!!!
{
gs[wz]--;
if(gs[wz]==)Update(wz,-);
}
L++;
}
while(L>q[i].l)
{
L--;
//wz=lower_bound(sz+1,sz+tot+1,color[L])-sz;
wz=color[L];
if(wz<=n+)
{
gs[wz]++;
if(gs[wz]==)Update(wz,);
}
}
while(R<q[i].r)
{
R++;
//wz=lower_bound(sz+1,sz+tot+1,color[R])-sz;
wz=color[R];
if(wz<=n+)
{
gs[wz]++;
if(gs[wz]==)Update(wz,);
}
}
while(R>q[i].r)
{
//wz=lower_bound(sz+1,sz+tot+1,color[R])-sz;
wz=color[R];
if(wz<=n+)
{
gs[wz]--;
if(gs[wz]==)Update(wz,-);
}
R--;
}
ans[q[i].id]=getans(,n+);
}
for(i=;i<=m;i++)printf("%d\n",ans[i]-);
fclose(stdin);
fclose(stdout);
return ;
}

Bzoj 3339: Rmq Problem && Bzoj 3585: mex 莫队,树状数组,二分的更多相关文章

  1. bzoj 3289: Mato的文件管理 莫队+树状数组

    3289: Mato的文件管理 Time Limit: 40 Sec  Memory Limit: 128 MB[Submit][Status][Discuss] Description Mato同学 ...

  2. BZOJ 3236 莫队+树状数组

    思路: 莫队+树状数组 (据说此题卡常数) yzy写了一天(偷笑) 复杂度有点儿爆炸 O(msqrt(n)logn) //By SiriusRen #include <cmath> #in ...

  3. BZOJ 3236: [Ahoi2013]作业(莫队+树状数组)

    传送门 解题思路 莫队+树状数组.把求\([a,b]\)搞成前缀和形式,剩下的比较裸吧,用\(cnt\)记一下数字出现次数.时间复杂度\(O(msqrt(n)log(n)\),莫名其妙过了. 代码 # ...

  4. bzoj3236 作业 莫队+树状数组

    莫队+树状数组 #include<cstdio> #include<cstring> #include<iostream> #include<algorith ...

  5. BZOJ_3289_Mato的文件管理_莫队+树状数组

    BZOJ_3289_Mato的文件管理_莫队+树状数组 Description Mato同学从各路神犇以各种方式(你们懂的)收集了许多资料,这些资料一共有n份,每份有一个大小和一个编号 .为了防止他人 ...

  6. BZOJ3236[Ahoi2013]作业——莫队+树状数组/莫队+分块

    题目描述 输入 输出 样例输入 3 4 1 2 2 1 2 1 3 1 2 1 1 1 3 1 3 2 3 2 3 样例输出 2 2 1 1 3 2 2 1 提示 N=100000,M=1000000 ...

  7. COGS.1822.[AHOI2013]作业(莫队 树状数组/分块)

    题目链接: COGS.BZOJ3236 Upd: 树状数组实现的是单点加 区间求和,采用值域分块可以\(O(1)\)修改\(O(sqrt(n))\)查询.同BZOJ3809. 莫队为\(O(n^{1. ...

  8. 51nod 1290 Counting Diff Pairs | 莫队 树状数组

    51nod 1290 Counting Diff Pairs | 莫队 树状数组 题面 一个长度为N的正整数数组A,给出一个数K以及Q个查询,每个查询包含2个数l和r,对于每个查询输出从A[i]到A[ ...

  9. 【BZOJ3460】Jc的宿舍(树上莫队+树状数组)

    点此看题面 大致题意: 一棵树,每个节点有一个人,他打水需要\(T_i\)的时间,每次询问两点之间所有人去打水的最小等待时间. 伪·强制在线 这题看似强制在线,但实际上,\(pre\ mod\ 2\) ...

随机推荐

  1. C++ map插入(insert)数据返回值

    例子: typedef boost::unordered_map<int, int> UserOnlineMap; UserOnlineMap userOnlineMap_; std::p ...

  2. 【BZOJ3884】【降幂大法】上帝与集合的正确用法

    Description 根据一些书上的记载,上帝的一次失败的创世经历是这样的: 第一天, 上帝创造了一个世界的基本元素,称做“元”. 第二天, 上帝创造了一个新的元素,称作“α”.“α”被定义为“元” ...

  3. MinGW 仿 linux 开发环境

    MinGW 默认安装 MSYS.通常打开的 MinGW Shell 其实 MSYS,MinGW 作为一个组件存在. MSYS -- Minimal SYStem,是一个 Bourne Shell 解释 ...

  4. Linux运维工程师面试

    一.Linux操作系统知识 1.常见的Linux发行版本都有什么?你最擅长哪一个?它的官网网站是什么?说明你擅长哪一块?   2.Linux开机启动流程详细步骤是什么?系统安装完,忘记密码如何破解? ...

  5. @font-face

     /**  * jQuery.hhNewSilder 滚动图片插件  * User: huanhuan  * QQ: 651471385  * Email: th.wanghuan@gmail.com ...

  6. c#代码自动修改解决方案下任意文件

    命名空间 using EnvDTE;using EnvDTE80; private DTE2 _applicationObject; public void AutoAddControl(插件 v_f ...

  7. appium的安装过程(图文界面)

    资料来源:http://www.cnblogs.com/fnng/p/4560298.html 1.准备安装材料

  8. Python学习笔记——正则表达式入门

    # 本文对正则知识不做详细解释,仅作入门级的正则知识目录. 正则表达式的强大早有耳闻,大一时参加一次选拔考试,题目就是用做个HTML解析器,正则的优势表现得淋漓尽致.题外话不多讲,直接上干货: 1. ...

  9. 版本控制工具git入门

    版本控制工具的历史 不说了,放张图 两者的区别:集中式需要一个中心服务器放置最新的文件,需要联网操作.分布式可以再不联网的情况下操作,前提要拥有版本库 git安装  略 github注册 略 如何在g ...

  10. 浅谈JavaScript的push()函数

    push() 方法可向数组的末尾添加一个或多个元素,并返回新的长度.返回值是把指定的值添加到数组后的新长度. 语法:arrayObject.push(newelement1,newelement2,. ...