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\) ...
随机推荐
- linux - 创建用户
apt-get update apt-get upgrade root@iZ28t2p7lz9Z:~# adduser cuiAdding user `cui' ...Adding new group ...
- Python编写的Linux网络设置脚本,Debian Wheezy上测试通过
hon编写的Linux网络设置脚本,Debian Wheezy上测试通过 阿里百川梦想创业大赛,500万创投寻找最赞的APP 技术细节参见Linux网络设置高级指南 注意事项参见程序注释 ...
- 网站开发常用jQuery插件总结(五)滚动条插件nanoscroller
网站在展示信息时,如果信息量过大,解决方法主要有三种.1.分页,将信息分页显示.2.整页显示,但是页面过长,影响浏览体验.3.使用滚动条,而默认滚动条样式太单一,用户体验不友好.所以我们需要美化滚动条 ...
- jquery 中的 $("#id") 与 document.getElementById("id") 的区别
以前没注意过,认为jquery 中的 $("#air") 与 document.getElementById("air") 是一回事,指的是同一个东西.在今天写 ...
- [C#]async/Await 使用小计
如果指定使用 异步 或 异步 修饰符,方法是异步方法,可以实现以下两个函数. • 清单异步方法可以使用 Await 或指定的 等待 悬挂点. 等待运算符通知编译器异步方法不能继续点的过去,直到等待 ...
- PDO操作mysql数据库(二)
从 MySQL 数据库读取数据 <?php $server = "localhost"; $user = "root"; $pwd = "123 ...
- 转载“用USBOOT制作DOS启动盘”
使用软件: Usboot和MaxDOS_5.6s_U盘版. 由于我的U盘容量比较小,暂时只能做DOS启动功能,其它功能如Windows PE,等我以后测试成功后再补充说明. U盘是啥? 读音优盘,可以 ...
- Windows 8 系统完全上手指南 - 非常详尽的 Win8 系统入门学习手册与使用技巧专题教程!
每次当有新版本的操作系统发布的时候,市面上总会冒出各种从入门到精通类的学习书籍,这次最新的 Windows 8 也不例外!不过,今天给大家送上免费的大礼——<Windows 8 完全上手指南&g ...
- APNs推送, 处理通知
设备接到apns发来的通知,应用处理通知有以下几种情况: 1. 应用还没有加载 这时如果点击通知的显示按钮,会调用didFinishLaunchingWithOptions,不会调用didReceiv ...
- PHP练习题(一)
程序1 .题目: 企业发放的奖金根据利润提成.利润(I)低于或等于10万元时,奖金可提10% : 利润高于10 万元, 低于20 万元时, 低于10万元的部分按10% 提成,高于 10万元的部分,可提 ...