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. ssh命令:隧道代理+本地端口转发+远程端口转发

        0.前言 nc是一个在网络连接两端的好工具,同时也是也个临时的端口转发的好工具.(永久的端口转发用什么?用iptables) ssh也是这方面的好工具,好处是加密可靠可复用在一端操作即可,代价 ...

  2. 【原创】Android开发使用华为手机调试logcat没有应用输出信息

    输入 *#*#2846579#*#* 点击project Menu点击后台 1.设置logcat 2. Dump & Log",打开开关"打开Dump & Log& ...

  3. C语言库函数--操作文件

    //C库函数读取文件的代码 I/O缓冲机制 C语言库函数写文件都是写在内存中,然后一次写入磁盘.提高了效率. 读写文件,不对系统进行操作,一般采用C语言库函数.移植可以在任何可以对C支持的操作系统,而 ...

  4. 网站开发常用jQuery插件总结(12)固定元素插件scrolltofixed

    这个插件在前段时间用过一次,当时是改一个网站.要求顶部的菜单栏随着滚动条的滚动而固定.也大体写了一下,不过在文章中也只是提了一下,文章地址:jQuery插件固定元素位置. 在这篇文章中,再进行总结一下 ...

  5. PHP 面向对象之自定义类

    所谓面向对象就是什么时候什么东西做什么,我们设计类的时候需要想的就是怎么做的内容,那么怎么样的一个类才算是符合OOP的思想呢,答案是:这个类写好之后,在使用的过程中,能准确的代表一个事物,在书写的时候 ...

  6. Qt之json解析

    Jsoner::Jsoner(QObject *parent) : QObject(parent){    QJsonObject json;    json.insert("loginna ...

  7. C# ADO.NET操作数据库 SqlHelp.cs类

    刚开始练习ADONET的时候,练习的一个SQLHelp.cs  数据库操作类,很简单,但是也很实用 using System; using System.Collections.Generic; us ...

  8. U盘装系统出现错误 安装失败怎么办

    在用U盘装系统的时候,有些用户犹豫第一次操作,经常会遇到一些问题.例如U盘装系统失败;U盘容量已用完;内存损坏等种种问题.因此小编整理了一些关于U盘装系统失败的常见问题解答,希望对大家有帮助! 1. ...

  9. linux禁止root用户直接登录sshd并修改默认端口

    linux最高权限用户root,默认可以直接登录sshd.为了提高服务器的安全度,需要对它进行禁止,使得攻击者无法通过暴力破解来获取root权限. 1,新建一个用户: #useradd xxx (xx ...

  10. 不用第三个变量,将a,b两个值互换,会出现什么样的异常?

    1 相互加减 a = a + b; b = a - b; a = a - b; 但会出现异常 如果a+b超过a类型的范围,俗称溢出异常. 2 指针操作交换地址 3 异或操作 转自网络搜索的答案