4408: [Fjoi 2016]神秘数

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 475  Solved: 287
[Submit][Status][Discuss]

Description

一个可重复数字集合S的神秘数定义为最小的不能被S的子集的和表示的正整数。例如S={1,1,1,4,13},

1 = 1

2 = 1+1

3 = 1+1+1

4 = 4

5 = 4+1

6 = 4+1+1

7 = 4+1+1+1

8无法表示为集合S的子集的和,故集合S的神秘数为8。

现给定n个正整数a[1]..a[n],m个询问,每次询问给定一个区间[l,r](l<=r),求由a[l],a[l+1],…,a[r]所构成的可重复数字集合的神秘数。

Input

第一行一个整数n,表示数字个数。
第二行n个整数,从1编号。
第三行一个整数m,表示询问个数。
以下m行,每行一对整数l,r,表示一个询问。

Output

对于每个询问,输出一行对应的答案。

Sample Input

5
1 2 4 9 10
5
1 1
1 2
1 3
1 4
1 5

Sample Output

2
4
8
8
8

HINT

对于100%的数据点,n,m <= 100000,∑a[i] <= 10^9

Source

鸣谢yyh上传

Solution

这道题挺好的思路。

首先考虑在集合中已经选出$k$个数的时候,再加入第$k+1$个数的情况。

显然有当$a_{k+1}>\sum ^{k}_{i=1} a_{k} +1$时,$ans=\sum ^{k}_{i=1} a_{k}+1$

否则显然这个这些数能组合出的范围扩大$a_{k+1}$

所以思路就是对于一个$ans$,求出$\sum ^{R}_{i=L} (a_{i}<ans) a_{i}$,如果这些数能组合到$ans$,那么这个$ans$只能扩大,所以把$ans$扩大到$\sum ^{R}_{i=L} (a_{i}<ans) a_{i} +1$继续做,否则得到神秘数。

所以支持这样做的还是利用可持久化线段树求出。

但是这样的复杂度还是比较暴力的,不过题目中说了$\sum a_{i}<10^{9}$所以复杂度最坏是 $O(MlogNlog10^{9})$

话说这题被xyx秒了....

Code

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
inline int read()
{
int x=0,f=1; char ch=getchar();
while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
return x*f;
}
#define MAXN 100010 int N,M,a[MAXN]; namespace PrTree{
int root[MAXN],sum[MAXN*20],lson[MAXN*20],rson[MAXN*20],sz;
inline void Insert(int l,int r,int &x,int last,int pos,int val)
{
x=++sz;
lson[x]=lson[last],rson[x]=rson[last];
sum[x]=sum[last]+val;
if (l==r) return;
int mid=(l+r)>>1;
if (pos<=mid) Insert(l,mid,lson[x],lson[last],pos,val);
else Insert(mid+1,r,rson[x],rson[last],pos,val);
}
inline int Query(int l,int r,int L,int R,int x,int y)
{
if (L>R) return 0;
if (L<=l && R>=r) return sum[y]-sum[x];
int mid=(l+r)>>1,re=0;
if (L<=mid) re+=Query(l,mid,L,R,lson[x],lson[y]);
if (R>mid) re+=Query(mid+1,r,L,R,rson[x],rson[y]);
return re;
}
}using namespace PrTree; int ls[MAXN]; int main()
{
N=read();
for (int i=1; i<=N; i++) ls[i]=a[i]=read(); sort(ls+1,ls+N+1); int tot=unique(ls+1,ls+N+1)-ls-1; for (int i=1; i<=N; i++) a[i]=lower_bound(ls+1,ls+tot+1,a[i])-ls; for (int i=1; i<=N; i++) PrTree::Insert(1,tot,root[i],root[i-1],a[i],ls[a[i]]); M=read();
while (M--) {
int l=read(),r=read();
int ans=1,up,pos;
while (1) {
pos=upper_bound(ls+1,ls+tot+1,ans)-ls-1;
if (ans<=(up=PrTree::Query(1,tot,1,pos,root[l-1],root[r])))
ans=up+1;
else break;
}
printf("%d\n",ans);
}
return 0;
}

  

【BZOJ-4408】神秘数 可持久化线段树的更多相关文章

  1. (bzoj4408)[FJOI2016]神秘数(可持久化线段树)

    (bzoj4408)[FJOI2016]神秘数(可持久化线段树) bzoj luogu 对于一个区间的数,排序之后从左到右每一个数扫 如果扫到某个数a时已经证明了前面的数能表示[1,x],那么分情况: ...

  2. Bzoj 4408: [Fjoi 2016]神秘数 可持久化线段树,神题

    4408: [Fjoi 2016]神秘数 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 177  Solved: 128[Submit][Status ...

  3. BZOJ 4408: [Fjoi 2016]神秘数 可持久化线段树

    4408: [Fjoi 2016]神秘数 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=4408 Description 一个可重复数字集 ...

  4. BZOJ 4408 FJOI2016 神秘数 可持久化线段树

    Description 一个可重复数字集合S的神秘数定义为最小的不能被S的子集的和表示的正整数.例如S={1,1,1,4,13},1 = 12 = 1+13 = 1+1+14 = 45 = 4+16 ...

  5. 51Nod 1175 区间中第K大的数 (可持久化线段树+离散)

    1175 区间中第K大的数 基准时间限制:1 秒 空间限制:131072 KB 分值: 160 难度:6级算法题   一个长度为N的整数序列,编号0 - N - 1.进行Q次查询,查询编号i至j的所有 ...

  6. bzoj 2653 二分答案+可持久化线段树

    首先离散化,然后我们知道如果对于一个询问的区间[l1,r1],[l2,r2],我们二分到一个答案x,将[l1,r2]区间中的元素大于等于x的设为1,其余的设为-1,那么如果[l1,r1]的最大右区间和 ...

  7. bzoj 2653 middle (可持久化线段树)

    middle Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 1981  Solved: 1097[Submit][Status][Discuss] D ...

  8. BZOJ 3542 [Poi2014]Couriers ——可持久化线段树

    [题目分析] 查找区间内出现次数大于一半的数字. 直接用主席树,线段树上维护区间大小,由于要求出现次数大于一半,每到一个节点可以分治下去. 时间复杂度(N+Q)logN [代码] #include & ...

  9. BZOJ 4408 神秘数

    题解同各神犇的方法... #include<iostream> #include<cstdio> #include<cstring> #include<alg ...

随机推荐

  1. Jenkins 01——简介

    Jenkins是一个开源软件项目,一个可扩展的持续集成引擎.旨在提供一个开放易用的软件平台,使软件的持续集成变成可能. 持续集成是一种开发实践,需要开发人员定期将代码集成到共享存储库中.这个概念意在消 ...

  2. 小议 开源中国 I LOVE YOU js代码

    今天在开源中国看到一篇神作<I LOVE YOU js代码>是17号的文章了,也许你已经看过了. 文章非常有意思,由 5 个 "爱心" 组成的一段js代码,能正常执行, ...

  3. html5 canvas画布上合成

    source-over 默认.在目标图像上显示源图像. source-atop 在目标图像顶部显示源图像.源图像位于目标图像之外的部分是不可见的. source-in 在目标图像中显示源图像.只有目标 ...

  4. 20145234黄斐《Java程序设计》第八周

    教材学习内容总结 第十四章-NIO与NIO2 NIO与IO的区别 NIO Channel继承框架 想要取得Channel的操作对象,可以使用Channels类,它定义了静态方法newChannel() ...

  5. 第10月第10天 git

    1. 已经用 git commit  提交了代码. 此命令可以用来回退到任意版本:git reset --hard  commitid https://www.cnblogs.com/qufanblo ...

  6. Oracle错误及解决方案

    1.ORA-00257:归档程序错误.在释放之前仅限于内部链接 问题原因:归档日志占满了空间 解决方法: .增加归档日志空间 alter system set db_recovery_file_des ...

  7. eclipse安装阿里巴巴java开发规范插件

    阿里巴巴java开发规范插件 作为JAVA开发人员,始终没有一个明确的规范,何为好代码,何为坏代码,造成不同人的代码风格不同,接手别人代码后改造起来相当困难.前不久,阿里巴巴发布了<阿里巴巴Ja ...

  8. Git GUI可视化操作教程

    1.在本地新建版本库 首先,我们打开Git GUI是这样的一个界面,选择第一项,新建版本库.  然后选择你需要进行版本管理的项目路径,我选择了一个LoginDemo的项目.  当你创建了版本库的时候, ...

  9. Mac安装MAT报错问题

    安装mat报错,提示在/.eclipse/1528649425_macosx_cocoa_x86_64/configuration/1539332382530.log路径下查看错误日志, 原因是/pr ...

  10. maven dependencies 报错

    maven配置的环境变量有问题: 用最新的maven替换系统默认的setting.xml文件即可