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,求由a[l],a[l+1],…,a[r]所构成的可重复数字集合的神秘数。

Hint

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

Solution

若当前神秘数为Ans,那么[1,Ans-1]都可以表示出来

如果当前加入一个数字a,分两种情况

  1. 若a<=Ans,区间变为[1,Ans+a-1],然后神秘数变成Ans+a
  2. 若a>Ans,Ans不变

Ans从1开始计算,每次计算小于Ans的数的和sum,然后Ans更新为sum+1

Code

#include <cstdio>
#include <algorithm>
#define N 100010
using namespace std;int n,m,A[N],rank[N],tot,T[N],ls[N*40],rs[N*40],s[N*40],Ans,sum;inline int read(){int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;
}void update(int last,int p,int l,int r,int &rt){rt=++tot;s[rt]=s[last]+p;ls[rt]=ls[last],rs[rt]=rs[last];if(l==r) return;int m=(l+r)>>1;if(p<=m) update(ls[last],p,l,m,ls[rt]);else update(rs[last],p,m+1,r,rs[rt]);
}int query(int ss,int tt,int l,int r){if(l==r) return s[tt]-s[ss];int m=(l+r)>>1;if(Ans<=m) return query(ls[ss],ls[tt],l,m);else return query(rs[ss],rs[tt],m+1,r)+s[ls[tt]]-s[ls[ss]];
}int main(){n=read();for(int i=1;i<=n;++i) sum+=(A[i]=read());for(int i=1;i<=n;++i) update(T[i-1],A[i],1,sum,T[i]);m=read();while(m--){int l=read(),r=read();Ans=1;for(;;){int t=query(T[l-1],T[r],1,sum);if(t<Ans) break;Ans=t+1;}printf("%d\n",Ans);}return 0;
}

转载于:https://www.cnblogs.com/void-f/p/8678640.html

[Bzoj4408]神秘数(主席树)相关推荐

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

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

  2. BZOJ44084299[Fjoi 2016]神秘数——主席树

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

  3. bzoj 4408: [FJOI2016]神秘数 主席树

    先看一下对于给定的一段如何暴力求最大值,首先将这一段排序,然后如果存在某一个数,这个数比它前面的数的前缀和至少大2,那么答案就是它前面那个数的前缀和+1. 那么假设现在处理了前面较小的一些数之后的答案 ...

  4. LUOGU P4587 [FJOI2016]神秘数(主席树)

    传送门 解题思路 如果区间内没有\(1\),那么答案就为\(1\),从这一点继续归纳.如果区间内有\(x\)个\(1\),设区间内\([2,x+1]\)的和为\(sum\),如果\(sum=0\),那 ...

  5. [FJOI 2016]bzoj 4408 神秘数 - 线段树

    题目大意:给你一列数,多次询问用一个区间的数字形成一个可重集合,最小的不能被表示为其一个子集的数字是多少. 题解:考虑给你一个可重集合你怎么算:从小到大排序,假设用前x个数字不能表示的最小都数字是an ...

  6. COGS 930. [河南省队2012] 找第k小的数 主席树

    主席树裸板子 #include<cstdio> #include<iostream> #include<algorithm> #define MAXN 100005 ...

  7. [BZOJ4408][FJOI2016]神秘数(主席树)

    题目: 我是超链接 题解: 如果[1,x]可以取到,我们加入一个数y,如果y<=x+1,那么我们有新的取数集合[1,x+y]:如果y>x+1,那么x+1还是取不到啊,这样我们就有了一个暴力 ...

  8. P4587-[FJOI2016]神秘数【主席树】

    正题 题目链接:https://www.luogu.com.cn/problem/P4587 题目大意 nnn个数,每次选择一个区间,然后询问这个区间的子集和所不能表示的最小的正整数. 解题思路 假设 ...

  9. 【FJOI2016】【BZOJ4408】神秘数

    [题目链接] BZOJ4408(权限题) [前置技能] 主席树 [题解] 首先先考虑一种时间复杂度为O(QNlogN)O(QNlogN)O(QNlogN)的暴力做法:将所有数按从小到大排序,考虑做到第 ...

最新文章

  1. 3D广告建模-C4D Octane渲染视频教程
  2. IDEA下——Spring入门程序
  3. Linux用户权限管理
  4. 若依 v4.6.1 后台 排除log4j
  5. 开发日记-20190328 关键词 利用eolinker一键快速生成API接口文档
  6. pythonsorted_[转].Python中sorted函数的用法
  7. python多列填充缺点_在Python中比较多列中的值并在另一列中添加新值
  8. IP、TCP、UDP数据包长度问题
  9. Atcoder Keyence Programming Contest 2020 D - Swap and Flip
  10. 企业实战(Jenkins+GitLab+SonarQube)_02_Jenkins运行
  11. python接口自动化(九)--python中字典和json的区别(详解)
  12. do…while 第二讲
  13. PaddlePaddle常用镜像
  14. 基于YUM安装与源码编译或二进制多实例安装Mariadb,mysql
  15. Linux:rm命令的用法
  16. cl_salv_table
  17. 人力资源管理专业知识与实务(初级)【7】
  18. 题解 [CF1682D] Circular Spanning Tree
  19. 花了一年时间开发的三维弯管机交互式转档软件(三维管子模型UG,SOLIDWORK,PRO/E文件转成YBC)...
  20. QBitmap 单色图片

热门文章

  1. Python显示图像
  2. vim中权限不足时不用退出而强制保存
  3. [Head First设计模式]身边的设计模式——适配器模式
  4. shell下的seq用法
  5. Citrix VDI实战攻略之五:vDisk配置
  6. Hibernate 配置 p6spy 显示完整 sql 语句
  7. python储存在ftp_python实现FTP
  8. excel甘特图模板_类似这样的甘特图是怎么做的?
  9. 计算机什么时候学汇编,[计算机基础] 汇编学习(1)
  10. python获取数据库用户名密码_在数据库中存储用户和密码