https://www.lydsy.com/JudgeOnline/problem.php?id=4299

一个可重复数字集合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

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

题解
A : 
将a从小到大排序,设当前神秘数为ans,扫到了a[i],那么
1. a[i] < ans 时, ans = ans + a[i] ;
2. a[i] > ans时, ans就是最小的神秘数, 跳出循环. 
B : 
我们也可以发现神秘数简化推法,ans初始为1,那么下一个ans为(sigma (a[i]<=ans) a[i])+1 . (用A部分方法压缩的想法来思考 [ lastans , nowans ) 区间内数的填充), 能够看出sigma的次数是log级的. 
此时我们需要维护的是任意区间内的sigma, 主席树可以实现. 
这里的主席树并没有离散化,因为主席树只需要建 n*( log总长 ) 个点, 这样写更方便 ( 常数变大了但是并不是很影响复杂度 ), 离散化也阔以, 不过注意一下查找的时候用upper_bound. 
 
(在这里mark一下lower_bound和upper_bound的方向)
 
 
 #include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
const int maxn=;
int n,m,cnt=,tot=;
int a[maxn]={},rt[maxn]={};
int sum[maxn*]={},lc[maxn*]={},rc[maxn*]={};
int read(){
int w=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){w=w*+ch-'';ch=getchar();}
return w*f;
}
void Build(int l,int r,int y,int &x,int v){
x=++tot;sum[x]=sum[y]+v;
if(l==r)return;
lc[x]=lc[y];rc[x]=rc[y];
int mid=(l+r)/;
if(v<=mid) Build(l,mid,lc[y],lc[x],v);
else Build(mid+,r,rc[y],rc[x],v);
}
int Query(int l,int r,int x,int y,int v){
if(l==r)return sum[y]-sum[x];
//cout<<sum[y]<<sum[x]<<l<<r<<endl;
int mid=(l+r)/;
if(v<=mid) return Query(l,mid,lc[x],lc[y],v);
else return Query(mid+,r,rc[x],rc[y],v)+sum[lc[y]]-sum[lc[x]];
}
int main(){
//freopen("a.in","r",stdin);
//freopen("a.out","w",stdout);
n=read();
for(int i=;i<=n;i++){a[i]=read();cnt+=a[i];}
for(int i=;i<=n;i++)Build(,cnt,rt[i-],rt[i],a[i]);
m=read();
for(int i=;i<=m;i++){
int l=read();int r=read();
int ans=;
for(;;){
int z=Query(,cnt,rt[l-],rt[r],ans);
//cout<<z<<endl;
if(z<ans)break;
ans=z+;
}
printf("%d\n",ans);
}
return ;
}

bzoj 4408: [Fjoi 2016]神秘数 数学 可持久化线段树 主席树的更多相关文章

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

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

  2. BZOJ 4408: [Fjoi 2016]神秘数

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

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

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

  4. BZOJ 4408: [Fjoi 2016]神秘数 [主席树]

    传送门 题意: 一个可重复数字集合S的神秘数定义为最小的不能被S的子集的和表示的正整数.例如S={1,1,1,4,13},8无法表示为集合S的子集的和,故集合S的神秘数为8.现给定n个正整数a[1]. ...

  5. ●BZOJ 4408 [Fjoi 2016]神秘数

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=4408 题解: 主席树 首先,对于一些数来说, 如果可以我们可以使得其中的某些数能够拼出 1- ...

  6. BZOJ 4408: [Fjoi 2016]神秘数 主席树 + 神题

    Code: #include<bits/stdc++.h> #define lson ls[x] #define mid ((l+r)>>1) #define rson rs[ ...

  7. 4408: [Fjoi 2016]神秘数

    4408: [Fjoi 2016]神秘数 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 452  Solved: 273 [Submit][Stat ...

  8. [BZOJ4408][Fjoi 2016]神秘数

    [BZOJ4408][Fjoi 2016]神秘数 试题描述 一个可重复数字集合S的神秘数定义为最小的不能被S的子集的和表示的正整数.例如S={1,1,1,4,13},1 = 12 = 1+13 = 1 ...

  9. 【BZOJ4408】[Fjoi 2016]神秘数 主席树神题

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

随机推荐

  1. 【总结】2017年当下最值得你关注的前端开发框架,不知道你就OUT了!

    近几年随着 jQuery.Ext 以及 CSS3 的发展,以 Bootstrap 为代表的前端开发框架如雨后春笋般挤入视野,可谓应接不暇. 在这篇分享中,我将总结2017年当下最值得你关注的前端开发框 ...

  2. POI读取Excel数据保存到数据库,并反馈给用户处理信息(导入带模板的数据)

    今天遇到这么一个需求,将课程信息以Excel的形式导入数据库,并且课程编号再数据库中不能重复,也就是我们需要先读取Excel提取信息之后保存到数据库,并将处理的信息反馈给用户.于是想到了POI读取文件 ...

  3. jq 判断鼠标滚动上下

    $(document).on("mousewheel DOMMouseScroll", function (e) { var delta = (e.originalEvent.wh ...

  4. Shell-help格式详解

    前言 linux shell命令通常可以通过-h或--help来打印帮助说明,或者通过man命令来查看帮助,有时候我们也会给自己的程序写简单的帮助说明,其实帮助说明格式是有规律可循的 帮助示例 下面是 ...

  5. MySQL 5.7半同步复制after sync和after commit详解【转】

    如果你的生产库开启了半同步复制,那么对数据的一致性会要求较高,但在MySQL5.5/5.6里,会存在数据不一致的风险.有这么一个场景,客户端提交了一个事务,master把binlog发送给slave, ...

  6. 【hdu6334】【2018Multi-University-Training Contest04】Problem C. Problems on a Tree

    维护1边的联通块和2边的联通块,合并的时候直接启发式合并. cdqz的大爷好强啊. #include<bits/stdc++.h> #define lson (o<<1) #d ...

  7. 栈应用之 背包问题(Python 版)

    栈应用之 背包问题 背包问题描述:一个背包里可以放入重量为weight的物品,现有n件物品的集合s,其中物品的重量为别为w0,w1,...,wn-1.问题是能否从中选出若干件物品,其重量之和正好等于w ...

  8. Linux下的输入/输出重定向

    Linux环境中支持输入输出重定向,用符号<和>来表示.0.1和2分别表示标准输入.标准输出和标准错误信息输出,可以用来指定需要重定向的标准输入或输出,比如 2>lee.dat 表示 ...

  9. JS格式化时间并比较

    JS格式化时间,然后进行比较.工作遇到的情况,然后网上找到的,记下来,下次用! </head> <body> <button onclick="myFuncti ...

  10. entityframework导航属性筛选

    ); //会在sql代码中生成Street = "上海"代码 var address1 = db.Entry(user).Collection(b => b.Address) ...