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. VUE项目用hbuilder 打包为手机APP

    一.测试项目是否可以正确运行    指令:npm run dev 首先我们先建立一个vue的项目,本人用的是vue-cli随便建立的,然后运行项目 不必非得是像我这样的,这一步的目的只是测试一下咱们的 ...

  2. linux环境下mysql默认是区分表名大小写的

    在linux环境下,mysql默认表明是区分大小写的,我们可以查看全局变量发现: mysql> show variables like 'lower%'; +------------------ ...

  3. MVVM模式的命令绑定

    命令绑定要达到的效果 命令绑定要关注的核心就是两个方面的问题,命令能否执行和命令怎么执行.也就是说当View中的一个Button绑定了ViewModel中一个命令后,什么时候这个Button是可用的, ...

  4. centos7.2系统没有eth0网卡

    最近一直在学centos7.5系统,偶然看到虚拟机里有7.2系统所以想练习一下(其实7.2和7.5差不多),但是打开虚拟机之后,发现没有eth0网卡 那没有eth0网卡就无法远程连接ssh,既然遇到了 ...

  5. 分布式git

    分布式 Git 你现在拥有了一个远程 Git 版本库,能为所有开发者共享代码提供服务,在一个本地工作流程下,你也已经熟悉 了基本 Git 命令.你现在可以学习如何利用 Git 提供的一些分布式工作流程 ...

  6. Win2003不显示移动硬盘、U盘解决方法

    Win2003已经识别出了“移动硬盘”,只是没有分配盘符. 解决方法:插入移动硬盘,右键单击“我的电脑”,选择“管理”,进入“计算机管理”,点击“存储”下面的“磁盘管理”.可以看到现在计算机中有两个磁 ...

  7. java基础51 IO流技术(打印流)

    1.打印流(printStream)的概念 打印流可以打印任意的数据类型 2.printStream的步骤 1.找到目标文件    2.创建一个打印流    3.打印信息    4.关闭资源 3.实例 ...

  8. MyBatis框架的基本使用

    MyBatis框架简介 MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名 ...

  9. 浮动元素垂直居中,bootstrap栅格布局垂直居中

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

  10. WinForm界面开发之 启动界面

    我们在开发桌面应用程序的时候,由于程序启动比较慢,往往为了提高用户的体验,增加一个闪屏,也就是SplashScreen,好处有:1.让用户看到加载的过程,提高程序的交互响应:2.可以简短展示或者介绍程 ...