题目描述

一个可重复数字集合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]所构成的可重复数字集合的神秘数。

输入

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

输出

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

样例输入

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

样例输出

2
4
8
8
8

提示

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

很有思维含量的一道主席树,要考虑的问题就是一个序列的神秘数。我们假设已经处理完了前面一些较小数的神秘数ans(ans刚开始是1),如果小于等于ans的数的和是sum(sum显然一定>=ans-1)。当sum<ans(即sum=ans-1)时,这个序列的神秘数就是ans,因为这些数(即之前所说的那些较小的数)最大能表示ans-1,而剩下数都比ans大,无法表示ans。当sum>=ans时,1~sum的数都能表示,假设比ans小的数中除去那些较小的数剩下的是a1,a2,a3……,那么1~ans-1+a1都能表示(因为ans~ans+a1-1中的任意一个数减a1一定小于ans,即一定能由那些较小的数表示),这时较小的数与a1的神秘数就是ans+a1。再将a2加进去,那么1~ans+a1+a2-1的数也就都能表示,以此类推就能得到1~sum的数都能表示。每次只要查询主席树上的前缀和与ans判断一下然后再更新ans就好了。

#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<cstdio>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int n,m;
int x,y;
int cnt;
int v[100010];
int a[100010];
int root[100010];
int sum[6000010];
int ls[6000010];
int rs[6000010];
int updata(int pre,int l,int r,int v)
{
int rt=++cnt;
if(l==r)
{
sum[rt]=sum[pre]+a[v];
return rt;
}
ls[rt]=ls[pre];
rs[rt]=rs[pre];
sum[rt]=sum[pre]+a[v];
int mid=(l+r)>>1;
if(v<=mid)
{
ls[rt]=updata(ls[pre],l,mid,v);
}
else
{
rs[rt]=updata(rs[pre],mid+1,r,v);
}
return rt;
}
int query(int x,int y,int l,int r,int k)
{
if(l==r)
{
return sum[y]-sum[x];
}
int mid=(l+r)>>1;
if(k<=mid)
{
return query(ls[x],ls[y],l,mid,k);
}
else
{
return query(rs[x],rs[y],mid+1,r,k)+sum[ls[y]]-sum[ls[x]];
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
v[i]=a[i];
}
sort(a+1,a+1+n);
for(int i=1;i<=n;i++)
{
v[i]=lower_bound(a+1,a+1+n,v[i])-a;
}
for(int i=1;i<=n;i++)
{
root[i]=updata(root[i-1],1,n,v[i]);
}
a[n+1]=1<<30;
scanf("%d",&m);
for(int i=1;i<=m;i++)
{
scanf("%d%d",&x,&y);
int mx=1;
int ans;
if(upper_bound(a+1,a+2+n,mx)-a-1==0)
{
printf("1\n");
continue;
}
while((ans=query(root[x-1],root[y],1,n,upper_bound(a+1,a+2+n,mx)-a-1))>=mx)
{
mx=ans+1;
}
printf("%d\n",mx);
}
}

BZOJ4408&4299[Fjoi 2016]神秘数——主席树的更多相关文章

  1. 【bzoj4408】[Fjoi 2016]神秘数 主席树

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  9. 4408: [Fjoi 2016]神秘数

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

随机推荐

  1. javaweb1(小学生四则运算)

    一.设计思想 ①设计三个页面,分别为题数设置页面,题目显示页面以及结果显示页面. ②设计题数设置页面. ③从题数设置页面接收题数,作为循环次数. ④利用随机数生成相应符合条件表达式,并存入数据库. ⑤ ...

  2. kubernetes集群中对多个pod操作命令

    $ for i in 0 1; do kubectl exec web-$i -- sh -c 'echo hello $(hostname) > /usr/share/nginx/html/i ...

  3. STM32 printf()函数和scanf()函数重定向到串口

    STM32 printf()函数和scanf()函数重定向到串口 printf()函数和scanf()函数重定向 在学习STM32的时候,常常需要用串口来测试代码的正确与否,这时候就要要用到print ...

  4. 【Linux系统目录结构】

    登录系统后,在当前命令窗口下输入 ls / 你会看到 以下是对这些目录的解释: /bin bin是Binary的缩写.这个目录存放着最经常使用的命令. /boot 这里存放的是启动Linux时使用的一 ...

  5. 【dataX】阿里开源ETL工具——dataX简单上手

    一.概述 1.是什么? DataX 是阿里巴巴集团内被广泛使用的离线数据同步工具/平台,实现包括 MySQL.Oracle.SqlServer.Postgre.HDFS.Hive.ADS.HBase. ...

  6. kubectl客户端工具远程连接k8s集群

    一.概述 一般情况下,在k8smaster节点上集群管理工具kubectl是连接的本地http8080端口和apiserver进行通讯的,当然也可以通过https端口进行通讯前提是要生成证书.所以说k ...

  7. Zookeeper-相关流程

    选主流程: 当Zk进入恢复模式时,需要重新选举出一个新的leader,让所有的Server都恢复到一个正确的状态.Zk的选举算法有两种:一种是基于basic paxos实现的,一种是基于fast pa ...

  8. 【php增删改查实例】第十七节 - 用户登录(1)

    新建一个login文件,里面存放的就是用户登录的模块. <html> <head> <meta charset="utf-8"> <sty ...

  9. 基于uFUN开发板的心率计(二)动态阈值算法获取心率值

    前言 上一篇文章:基于uFUN开发板的心率计(一)DMA方式获取传感器数据,介绍了如何获取PulseSensor心率传感器的电压值,并对硬件电路进行了计算分析.心率计,重要的是要获取到心率值,本篇文章 ...

  10. slurm用户快速入门手册

    1. 概述2. 架构3. 命令3.1 sacct3.2 sattach3.4 sbatch3.5 sbcast3.6 scancel3.7 scontrol3.8 sinfo3.9 smap3.10 ...