题目描述

一个可重复数字集合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. Android学习之基础知识五—ListView控件(最常用和最难用的控件)

    ListView控件允许用户通过上下滑动来将屏幕外的数据拉到屏幕内,把屏幕内的数据拉到屏幕外. 一.ListView的简单用法第一步:先创建一个ListViewTest项目,在activity_mia ...

  2. ftp 传输数据:命令链路连接方法是一样的,而数据链路的建立方法就完全不同

    0.FTP协议有两种工作方式:PORT方式和PASV方式,中文意思为主动式和被动式. PORT(主动)连接过程是:客户端向服务器的FTP端口(默认是21)发送连接请 求,服务器接受连接,建立一条命令链 ...

  3. 开发板测试-GPRS

    注意事项: 经过测试,为了使STM32和Air202的串口稳定通信,需要更改 以前电路感觉应该是三极管控制极4.7K电阻太大,又因为开关速度快,然后开关的时候导致不足以让三极管处于全部导通状态,所以电 ...

  4. Zookeeper-相关流程

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

  5. 2011 noip 提高组

    首先吐槽:刚刚写着写着突然蓝屏了,,emmm,写到最后一题了蓝屏了. 当时我的内心是崩溃的. 然后,旁边的大佬默默来了一句:论保存草稿的重要性. 连着蓝了三次之后开了防火墙,然后,,我左边那位同学又开 ...

  6. dotnetcore/CAP

    CAP带你轻松玩转Asp.Net Core消息队列 CAP是什么? CAP是由我们园子里的杨晓东大神开发出来的一套分布式事务的决绝方案,是.Net Core Community中的第一个千星项目(目前 ...

  7. IntelliJ IDEA下自动生成Hibernate映射文件以及实体类

    来自:https://blog.csdn.net/chenyunqiang/article/details/81026823 1.构建项目并添加项目结构配置以及配置初始参数 1.1.如图将基本的架子搭 ...

  8. 通过git命令行从github或服务器上克隆、修改和更新项目

    项目开发时,为了方便版本管理,许多公司采用git来控制项目版本.简单介绍下: 第一步:在本地新建一个文件夹,作为本地仓库,如“test”.打开git bash,进入到该文件夹目录下,如下图: 第二步: ...

  9. Webpack 2 视频教程 004 - Webpack 初体验

    原文发表于我的技术博客 这是我免费发布的高质量超清「Webpack 2 视频教程」. Webpack 作为目前前端开发必备的框架,Webpack 发布了 2.0 版本,此视频就是基于 2.0 的版本讲 ...

  10. Shell学习笔记二

    一.调试脚本 调试功能是每一种编程语言都应该实现的重要特性之一,当出现一些始料未及的情况时,用它来生成脚本运行信息.调试信息可以帮你弄清楚是什么原因使得程序发生崩溃或行为异常.每位系统程序员都应该了解 ...