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. JavaScript 笔记总结

    一.js的简介  1.js是什么 js是可以嵌入到html中,是 基于对象 和 事件驱动 的 脚本语言 特点: (1)交互性 (2)安全性:js不能访问本地磁盘 (3)跨平台:浏览器中都具备js解析器 ...

  2. SpringBoot非官方教程 | 第十一篇:springboot集成swagger2,构建优雅的Restful API

    转载请标明出处: 原文首发于:https://www.fangzhipeng.com/springboot/2017/07/11/springboot-swagger2/ 本文出自方志朋的博客 swa ...

  3. oracle权限配置

    系统权限管理:1.系统权限分类:DBA: 拥有全部特权,是系统最高权限,只有DBA才可以创建数据库结构. RESOURCE:拥有Resource权限的用户只可以创建实体,不可以创建数据库结构. CON ...

  4. Less 常用基础知识

    LESS 中的注释 也可以额使用css 中的注释(/**/) 这种方式是可以被编译出来的. 也可以使用// 注释 不会被编译的 变量 声明变量的话一定要用@开头 例如:@变量名称:值: @test_w ...

  5. ES6 async await

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

  6. 【模板】概率dp

    有n个投资事件,和一个成功概率最低接受值rate.每个投资的价值是c[i],成功概率是p[i](浮点数). 在保证成功概率≥rate的情况下,使价值最大化. #include<bits/stdc ...

  7. jdbc学习笔记02

    数据库连接池 DBCP DataBase Conection Pool:数据库连接池 如果没有数据库连接池,每一次业务都需要服务器和数据库服务器建立一次连接,业务处理完连接断开,如果有1万次业务处理, ...

  8. git stash应用

    今天在看一个bug,之前一个分支的版本是正常的,在新的分支上上加了很多日志没找到原因,希望回溯到之前的版本,确定下从哪个提交引入的问题,但是还不想把现在的修改提交,也不希望在Git上看到当前修改的版本 ...

  9. Git推送到远程分支出错

    执行git push -u origin master fatal: 'git@github.com:qilinonline/git_test.git' does not appear to be a ...

  10. php常见面试(Smarty及相关知识)

    1.Smarty简介: 是一种php模板引擎,它分开了后台程序和前台页面内容,使程序员和美工分工合作.还有其它模版引擎实现同样的目的. 2.Smarty使用: 建立php文件: 包含smarty类文件 ...