[Bzoj4408]神秘数(主席树)
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,分两种情况
- 若a<=Ans,区间变为[1,Ans+a-1],然后神秘数变成Ans+a
- 若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]神秘数(主席树)相关推荐
- 【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 = ...
- 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 = ...
- bzoj 4408: [FJOI2016]神秘数 主席树
先看一下对于给定的一段如何暴力求最大值,首先将这一段排序,然后如果存在某一个数,这个数比它前面的数的前缀和至少大2,那么答案就是它前面那个数的前缀和+1. 那么假设现在处理了前面较小的一些数之后的答案 ...
- LUOGU P4587 [FJOI2016]神秘数(主席树)
传送门 解题思路 如果区间内没有\(1\),那么答案就为\(1\),从这一点继续归纳.如果区间内有\(x\)个\(1\),设区间内\([2,x+1]\)的和为\(sum\),如果\(sum=0\),那 ...
- [FJOI 2016]bzoj 4408 神秘数 - 线段树
题目大意:给你一列数,多次询问用一个区间的数字形成一个可重集合,最小的不能被表示为其一个子集的数字是多少. 题解:考虑给你一个可重集合你怎么算:从小到大排序,假设用前x个数字不能表示的最小都数字是an ...
- COGS 930. [河南省队2012] 找第k小的数 主席树
主席树裸板子 #include<cstdio> #include<iostream> #include<algorithm> #define MAXN 100005 ...
- [BZOJ4408][FJOI2016]神秘数(主席树)
题目: 我是超链接 题解: 如果[1,x]可以取到,我们加入一个数y,如果y<=x+1,那么我们有新的取数集合[1,x+y]:如果y>x+1,那么x+1还是取不到啊,这样我们就有了一个暴力 ...
- P4587-[FJOI2016]神秘数【主席树】
正题 题目链接:https://www.luogu.com.cn/problem/P4587 题目大意 nnn个数,每次选择一个区间,然后询问这个区间的子集和所不能表示的最小的正整数. 解题思路 假设 ...
- 【FJOI2016】【BZOJ4408】神秘数
[题目链接] BZOJ4408(权限题) [前置技能] 主席树 [题解] 首先先考虑一种时间复杂度为O(QNlogN)O(QNlogN)O(QNlogN)的暴力做法:将所有数按从小到大排序,考虑做到第 ...
最新文章
- 3D广告建模-C4D Octane渲染视频教程
- IDEA下——Spring入门程序
- Linux用户权限管理
- 若依 v4.6.1 后台 排除log4j
- 开发日记-20190328 关键词 利用eolinker一键快速生成API接口文档
- pythonsorted_[转].Python中sorted函数的用法
- python多列填充缺点_在Python中比较多列中的值并在另一列中添加新值
- IP、TCP、UDP数据包长度问题
- Atcoder Keyence Programming Contest 2020 D - Swap and Flip
- 企业实战(Jenkins+GitLab+SonarQube)_02_Jenkins运行
- python接口自动化(九)--python中字典和json的区别(详解)
- do…while 第二讲
- PaddlePaddle常用镜像
- 基于YUM安装与源码编译或二进制多实例安装Mariadb,mysql
- Linux:rm命令的用法
- cl_salv_table
- 人力资源管理专业知识与实务(初级)【7】
- 题解 [CF1682D] Circular Spanning Tree
- 花了一年时间开发的三维弯管机交互式转档软件(三维管子模型UG,SOLIDWORK,PRO/E文件转成YBC)...
- QBitmap 单色图片