Bzoj 3339: Rmq Problem && Bzoj 3585: mex 莫队,树状数组,二分
3339: Rmq Problem
Time Limit: 20 Sec Memory Limit: 128 MB
Submit: 833 Solved: 397
[Submit][Status][Discuss]
Description

Input

Output

Sample Input
0 2 1 0 1 3 2
1 3
2 3
1 4
3 6
2 7
Sample Output
0
3
2
4
HINT

Source
题解:
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 莫队,树状数组,二分的更多相关文章
- bzoj 3289: Mato的文件管理 莫队+树状数组
3289: Mato的文件管理 Time Limit: 40 Sec Memory Limit: 128 MB[Submit][Status][Discuss] Description Mato同学 ...
- BZOJ 3236 莫队+树状数组
思路: 莫队+树状数组 (据说此题卡常数) yzy写了一天(偷笑) 复杂度有点儿爆炸 O(msqrt(n)logn) //By SiriusRen #include <cmath> #in ...
- BZOJ 3236: [Ahoi2013]作业(莫队+树状数组)
传送门 解题思路 莫队+树状数组.把求\([a,b]\)搞成前缀和形式,剩下的比较裸吧,用\(cnt\)记一下数字出现次数.时间复杂度\(O(msqrt(n)log(n)\),莫名其妙过了. 代码 # ...
- bzoj3236 作业 莫队+树状数组
莫队+树状数组 #include<cstdio> #include<cstring> #include<iostream> #include<algorith ...
- BZOJ_3289_Mato的文件管理_莫队+树状数组
BZOJ_3289_Mato的文件管理_莫队+树状数组 Description Mato同学从各路神犇以各种方式(你们懂的)收集了许多资料,这些资料一共有n份,每份有一个大小和一个编号 .为了防止他人 ...
- 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 ...
- COGS.1822.[AHOI2013]作业(莫队 树状数组/分块)
题目链接: COGS.BZOJ3236 Upd: 树状数组实现的是单点加 区间求和,采用值域分块可以\(O(1)\)修改\(O(sqrt(n))\)查询.同BZOJ3809. 莫队为\(O(n^{1. ...
- 51nod 1290 Counting Diff Pairs | 莫队 树状数组
51nod 1290 Counting Diff Pairs | 莫队 树状数组 题面 一个长度为N的正整数数组A,给出一个数K以及Q个查询,每个查询包含2个数l和r,对于每个查询输出从A[i]到A[ ...
- 【BZOJ3460】Jc的宿舍(树上莫队+树状数组)
点此看题面 大致题意: 一棵树,每个节点有一个人,他打水需要\(T_i\)的时间,每次询问两点之间所有人去打水的最小等待时间. 伪·强制在线 这题看似强制在线,但实际上,\(pre\ mod\ 2\) ...
随机推荐
- nginx 限制及指定IP或IP段访问
nginx 限制及指定IP或IP段访问. location / { deny 192.168.1.1; allow ; allow ; deny all; } 企业问题案例:Nginx做反向代理的时候 ...
- vi简单快键命令
进入vi的命令 vi filename :打开或新建文件,并将光标置于第一行首 vi +n filename :打开文件,并将光标置于第n行首 vi + filename :打开文件,并将光标置于最后 ...
- FBX SDK 从2012.1 到 2013.3 变化
==================================================== ============================== 译文 ...
- php返回json数据函数实例
本文实例讲述了php返回json数据函数的用法,分享给大家供大家参考.具体方法如下: json_encode()函数用法: ? 1 echo json_encode(array('a'=>'bb ...
- C#中指针使用总结
C#为了类型安全,默认并不支持指针.但是也并不是说C#不支持指针,我们可以使用unsafe关键词,开启不安全代码(unsafe code)开发模式.在不安全模式下,我们可以直接操作内存,这样就可以使用 ...
- S3C2440的LCD虚拟显示测试
一.概述 S3C2440的LCD控制器支持虚拟显示,说的容易理解一点就是,可以显示比实际显示器大的图像.可以这样想象,有一个大的图片,但是显示器(显示串口)比较小,但是我们可以相对于大图片(即大图 ...
- POJ 2886 Who Gets the Most Candies? 线段树
题目: http://poj.org/problem?id=2886 左右转的果断晕,题目不难,关键是准确的转啊转.因为题目要求输出约数个数最多的数,所以预处理[1,500000]的约数的个数就行了. ...
- 介绍.NET Core
在connect (),我们宣布.NET 核心将能完全释放,作为开放源码软件.我也答应在.NET 核心跟更多的细节.在这篇文章,我将提供.NET 核心,我们如何去释放它,它涉及到.NET 框架,如何和 ...
- Rsync和FastDFS
在做分布式文件存储的时候,常常用到两个工具,Rsync和FastDFS:这两者本质的区别在于前者的实时性相面相对较差,需要手工编写脚本同步,然后在放到定时任务(cron)中:FastDFS自动实现同组 ...
- maven的安装,maven库配置和Eclipse插件的安装
maven的安装,maven库配置和Eclipse插件的安装 1.下载并解压maven 2.配置环境变量 3.配置maven配置文件 1.下载链接 Downloading Apache Maven 2 ...