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

题意极为简洁。。。。

可以发现这个题需要分析一些性质来判断一个数是否可以被凑出来。一个数被凑出来的时候一定不会用到大于它的数字,只可能会用到小于它的数字。

问题看起来很无序,那么找到一个考虑的顺序,把询问区间内所有的数字从小到大开始考虑。首先看有没有1,如果有,那么1就可以凑出来,同时可以发现如果有x个1,那么1~x都可以凑出来。那么考虑1~x范围内的所有数字,你可发现任何一个非1的数字都可以使我们可以连续表达的数字区间增大了(脑补一个移动的窗口),1~x区间内能表示出的最大数字就是 x+(区间内小于等于x的最大值)。仔细一想这正是一个同构子问题!

每一次都这样做,我们最多会扩大几次考虑范围呢?不难发现只要还有答案成立,这一次扩大之后的考虑范围至少是上一次的两倍,所以最多也就log级别。

于是我们只需要维护区间内小于等于某个数字的和就可以了,开心上一发主席树板子。

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<queue>
#include<set>
#include<map>
#include<vector>
#include<cctype>
using namespace std;
const int MAXN=; int N,M,AA[MAXN],rank[MAXN],tot;
struct persistable_segment_tree{
static const int maxn=;
static const int maxm=;
int root[maxm],np,lc[maxn],rc[maxn],sum[maxn];
persistable_segment_tree(){ np=; }
void pushup(int now){ sum[now]=sum[lc[now]]+sum[rc[now]]; }
void build(int &now,int L,int R){
now=++np,lc[now]=rc[now]=sum[now]=;
if(L==R) return;
int m=L+R>>;
build(lc[now],L,m); build(rc[now],m+,R);
}
int copynode(int now){
np++,lc[np]=lc[now],rc[np]=rc[now],sum[np]=sum[now];
return np;
}
void update(int &now,int L,int R,int pos,int v){
now=copynode(now);
if(L==R){ sum[now]+=v; return; }
int m=L+R>>;
if(pos<=m) update(lc[now],L,m,pos,v);
else update(rc[now],m+,R,pos,v);
pushup(now);
}
int query(int xx,int yy,int L,int R,int A,int B){
if(A<=L&&R<=B) return sum[yy]-sum[xx];
int m=L+R>>;
if(B<=m) return query(lc[xx],lc[yy],L,m,A,B);
if(A>m) return query(rc[xx],rc[yy],m+,R,A,B);
return query(lc[xx],lc[yy],L,m,A,B)+query(rc[xx],rc[yy],m+,R,A,B);
}
}st; void data_in()
{
scanf("%d",&N);
for(int i=;i<=N;i++) scanf("%d",&AA[i]);
scanf("%d",&M);
}
void work()
{
memcpy(rank,AA,sizeof(AA));
sort(rank+,rank+N+);
tot=unique(rank+,rank+N+)-rank;
st.build(st.root[],,tot-);
for(int i=;i<=N;i++){
st.root[i]=st.root[i-];
st.update(st.root[i],,tot-,lower_bound(rank+,rank+tot,AA[i])-rank,AA[i]);
}
int l,r,pos,ans,tmp;
for(int i=;i<=M;i++){
scanf("%d%d",&l,&r);
pos=upper_bound(rank+,rank+tot,)-rank-,ans=;
while(pos){
tmp=st.query(st.root[l-],st.root[r],,tot-,,pos);
if(tmp<ans) break;
ans=tmp+;
if(pos==tot-) break;
pos=upper_bound(rank+,rank+tot,ans)-rank-;
}
printf("%d\n",ans);
}
}
int main()
{
data_in();
work();
return ;
}

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

  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】神秘数 可持久化线段树

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

  5. [BZOJ 3123] [SDOI 2013]森林(可持久化线段树+并查集+启发式合并)

    [BZOJ 3123] [SDOI 2013]森林(可持久化线段树+启发式合并) 题面 给出一个n个节点m条边的森林,每个节点都有一个权值.有两种操作: Q x y k查询点x到点y路径上所有的权值中 ...

  6. BZOJ.2653.[国家集训队]middle(可持久化线段树 二分)

    BZOJ 洛谷 求中位数除了\(sort\)还有什么方法?二分一个数\(x\),把\(<x\)的数全设成\(-1\),\(\geq x\)的数设成\(1\),判断序列和是否非负. 对于询问\(( ...

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

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

  8. BZOJ 3653: 谈笑风生(DFS序+可持久化线段树)

    首先嘛,还是太弱了,想了好久QAQ 然后,这道题么,明显就是求sigma(size[x]) (x是y的儿子且层树小于k) 然后就可以发现:把前n个节点按深度建可持久化线段树,就能用前缀和维护了 其实不 ...

  9. bzoj 4504: K个串 可持久化线段树+堆

    题目: Description 兔子们在玩k个串的游戏.首先,它们拿出了一个长度为n的数字序列,选出其中的一 个连续子串,然后统计其子串中所有数字之和(注意这里重复出现的数字只被统计一次). 兔子们想 ...

随机推荐

  1. 通过ajax给后台提交数据时,radio性别数据的获取

    通过ajax向后台异步发送数据,经常我们会遇到个人信息额提交,一般我们采用FormData来装数据.在装性别值得时候,我们会有两个radio框,获取radio值得方法如下: 一般情况下,一个radio ...

  2. idea开启自动编译

    springboot+thymeleaf+idea   idea默认是不自动编译的. 首先热部署的jar包肯定是要加进去的 2,快捷键 ctrl+shift+alt+/       点击registr ...

  3. 解决问题的思路(如故事版里面有东西,却不见了)(swift里面开发比较多)

    解决问题的思路(如故事版里面有东西,却不见了) 正确效果图: 真机效果图: 内容:不见了 解决步骤:(重点讲解方法1) 1.把背景图隐藏了,如果能出现内容,说明背景图把内容遮住了.那怎么办呢,背景图是 ...

  4. NEC 工程师规范

    工程师规范 - 开发准备 了解产品和设计 参加需求.交互.视觉会议,了解产品设计和项目成员. 了解产品面向的设备和平台. 了解产品对兼容性的要求以及是否采用响应式设计等. 了解产品要使用的技术(WEB ...

  5. 技能get:用HTML5实现波浪效果

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  6. python查找目录及子目录下特定文件

    写这篇博客的缘由: 面试归来翻脉脉发现一个陌生的朋友提出一个面试题,设计实现遍历目录及子目录,抓取.pyc文件. 并贴出两种实现方法: 个人感觉,这两种方法中规中矩,不像是python的风格.pyth ...

  7. 3930: [CQOI2015]选数

    Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1958  Solved: 979[Submit][Status][Discuss] Descripti ...

  8. oracle的局部本地分区索引

    环境:oracle 12.2.0.1 注:未确定10g,11g是否有这些特性.现在基本不用10g,主要用12c,11g. 毫无疑问,这种 特性对于dba或者实施人员而言显得很重要,尤其当你的数据库主要 ...

  9. scala成长之路(4)compaion object——伴生对象的使用

    虽然java一直声称自己是完全面向对象的语言,但一直以来都被很多人所质疑,其中java的静态成员函数就是主要的“罪魁祸首”.由于java中保留了静态方法的调用,导致其编程模式依然有过程式编程的可能,尤 ...

  10. 微信公众号--JS-SDK

    JS-SDK 微信JS-SDK是微信公众平台 面向网页开发者提供的基于微信内的网页开发工具包. 通过使用微信JS-SDK,网页开发者可借助微信高效地使用拍照.选图.语音.位置等手机系统的能力,同时可以 ...