[bzoj4408][Fjoi2016]神秘数
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](l\;\leq\;r)$,求由$a[l],a[l+1],…,a[r]$所构成的可重复数字集合的神秘数。
Input
第一行一个整数$n$,表示数字个数。
第二行$n$个整数,从$1$编号。
第三行一个整数$m$,表示询问个数。
以下$m$行,每行一对整数$l,r$,表示一个询问。
Output
对于每个询问,输出一行对应的答案。
Sample Input
5
1 2 4 9 10
5
1 1
1 2
1 3
1 4
1 5
Sample Output
2
4
8
8
8
HINT
$n,m\;\leq\;10^5,\sum\;a[i]\;\leq\;10^9$
Solution
当$x$为答案时,满足条件$\sum_{a[i]\;\leq\;x}a[i]<x$
枚举$x$,用主席树求和,判断是否合法,若不合法,$x=\sum_{a[i]\;\leq\;x}a[i]$
#include<cmath>
#include<ctime>
#include<queue>
#include<stack>
#include<cstdio>
#include<vector>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define N 100005
#define M 2000005
using namespace std;
typedef long long ll;
struct linetree{
int l,r,s,lc,rc;ll t;
}lt[M];
int a[N],p[N],rt[N],n,m,l,r,siz,cnt,tmp;
inline void bld(int u,int l,int r,int k){
lt[u].l=l;lt[u].r=r;
if(k>=p[l]&&k<=p[r]){
lt[u].s=1;lt[u].t=(ll)(k);
}
if(lt[u].l<lt[u].r){
int mid=lt[u].l+lt[u].r>>1;
lt[u].lc=++cnt;bld(cnt,l,mid,k);
lt[u].rc=++cnt;bld(cnt,mid+1,r,k);
}
}
inline void build(int u,int lst,int l,int r,int k){
lt[u].l=l;lt[u].r=r;
lt[u].s=lt[lst].s+1;lt[u].t=lt[lst].t+(ll)(k);
if(lt[u].l<lt[u].r){
int mid=lt[u].l+lt[u].r>>1;
if(k<=p[mid]){
lt[u].lc=++cnt;
build(cnt,lt[lst].lc,l,mid,k);
if(lt[lst].rc) lt[u].rc=lt[lst].rc;
else{
lt[u].rc=++cnt;
build(cnt,lt[lst].rc,mid+1,r,k);
}
}
else{
lt[u].rc=++cnt;
build(cnt,lt[lst].rc,mid+1,r,k);
if(lt[lst].lc) lt[u].lc=lt[lst].lc;
else{
lt[u].lc=++cnt;
build(cnt,lt[lst].lc,l,mid,k);
}
}
}
}
inline ll ask(int u,int x){
if(!x||!u) return 0;
if(p[lt[u].r]<=x) return lt[u].t;
int mid=lt[u].l+lt[u].r>>1;
if(x<=p[mid]) return ask(lt[u].lc,x);
return lt[lt[u].lc].t+ask(lt[u].rc,x);
}
inline int chk(int u,int x){
if(!x||!u) return 0;
if(p[lt[u].r]<=x) return lt[u].s;
int mid=lt[u].l+lt[u].r>>1;
if(x<=p[mid]) return chk(lt[u].lc,x);
return lt[lt[u].lc].s+chk(lt[u].rc,x);
}
inline void Aireen(){
scanf("%d",&n);
for(int i=1;i<=n;++i){
scanf("%d",&a[i]);p[i]=a[i];
}
sort(p+1,p+1+n);
siz=1;
for(int i=2;i<=n;++i)
if(p[i]!=p[i-1]) p[++siz]=p[i];
rt[1]=++cnt;bld(cnt,1,siz,a[1]);
for(int i=2;i<=n;++i){
rt[i]=++cnt;
build(cnt,rt[i-1],1,siz,a[i]);
}
scanf("%d",&m);
while(m--){
scanf("%d%d",&l,&r);
for(ll i=0,s;;i=s+1ll){
s=ask(rt[r],i)-ask(rt[l-1],i);
if(s>=ask(rt[r],p[siz])-ask(rt[l-1],p[siz])){
printf("%lld\n",s+1ll);break;
}
tmp=upper_bound(p+1,p+1+siz,(int)(s+1ll))-p-1;
if(ask(rt[r],p[tmp])-ask(rt[l-1],p[tmp])<s+1ll){
printf("%lld\n",s+1ll); break;
}
}
}
}
int main(){
freopen("mystic.in","r",stdin);
freopen("mystic.out","w",stdout);
Aireen();
fclose(stdin);
fclose(stdout);
return 0;
}
[bzoj4408][Fjoi2016]神秘数的更多相关文章
- (bzoj4408)[FJOI2016]神秘数(可持久化线段树)
(bzoj4408)[FJOI2016]神秘数(可持久化线段树) bzoj luogu 对于一个区间的数,排序之后从左到右每一个数扫 如果扫到某个数a时已经证明了前面的数能表示[1,x],那么分情况: ...
- 题解【bzoj4587 & bzoj4408 [FJOI2016]神秘数】
Description \(n\) 个数的序列,每次询问一个区间,求最小的一个数使得不能用这个区间中的数之和表示. \(n \leq 10^5, \sum a_i \leq 10^9\) 这两个题一个 ...
- 【BZOJ4408】[FJOI2016]神秘数(主席树)
[BZOJ4408][FJOI2016]神秘数(主席树) 题面 BZOJ 洛谷 题解 考虑只有一次询问. 我们把所有数排个序,假设当前可以表示出的最大数是\(x\). 起始\(x=0\). 依次考虑接 ...
- 【LG4587】[FJOI2016]神秘数
[LG4587][FJOI2016]神秘数 题面 洛谷 题解 首先我们想一想暴力怎么做 对于一段区间\([l,r]\) 我们先将它之间的数升序排序 从左往右扫, 设当前我们可以表示出的数为\([1,x ...
- BZOJ4299 & CC FRBSUM:ForbiddenSum & BZOJ4408 & 洛谷4587 & LOJ2174:[FJOI2016]神秘数——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=4299 https://www.lydsy.com/JudgeOnline/problem.php? ...
- [FJOI2016]神秘数(脑洞+可持久化)
题目描述 一个可重复数字集合S的神秘数定义为最小的不能被S的子集的和表示的正整数.例如S={1,1,1,4,13}, 1 = 1 2 = 1+1 3 = 1+1+1 4 = 4 5 = 4+1 6 = ...
- Luogu P4587 [FJOI2016]神秘数
一道好冷门的好题啊,算是对于一个小结论和数据结构的一点考验吧 首先看完题目我们发现要从这个神秘数的性质入手,我们观察or手玩可得: 如果有\(x\)个\(1\),那么\([1,x]\)都是可以表示出来 ...
- 【BZOJ-4408】神秘数 可持久化线段树
4408: [Fjoi 2016]神秘数 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 475 Solved: 287[Submit][Status ...
- BZOJ 4408 FJOI2016 神秘数 可持久化线段树
Description 一个可重复数字集合S的神秘数定义为最小的不能被S的子集的和表示的正整数.例如S={1,1,1,4,13},1 = 12 = 1+13 = 1+1+14 = 45 = 4+16 ...
随机推荐
- linux负载均衡总结性说明(四层负载/七层负载)
在常规运维工作中,经常会运用到负载均衡服务.负载均衡分为四层负载和七层负载,那么这两者之间有什么不同?废话不多说,详解如下: 一,什么是负载均衡1)负载均衡(Load Balance)建立在现有网络结 ...
- Delphi常用系统函数总结
Delphi常用系统函数总结 字符串处理函数 Unit System 函数原型 function Concat(s1 [, s2,..., sn]: string): string; 说明 与 S : ...
- 【BZOJ 1001】[BeiJing2006]狼抓兔子
Description 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的,而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一个 ...
- 苹果系统里面部署ASP.NET
需要在global文件里设置一下 protected void Application_Start() { AreaRegistration.RegisterAllAreas(); FilterCon ...
- [转]WampServer localhost 图标不显示解决办法
FROM : http://blog.warmcolor.net/2011/11/03/wampserver-localhost-%E5%9B%BE%E6%A0%87%E4%B8%8D%E6%98%B ...
- eclipse/intellij idea 远程调试hadoop 2.6.0
很多hadoop初学者估计都我一样,由于没有足够的机器资源,只能在虚拟机里弄一个linux安装hadoop的伪分布,然后在host机上win7里使用eclipse或Intellj idea来写代码测试 ...
- DispatcherHelper
DispatcherHelper 通常,WPF 应用程序从两个线程开始:一个用于处理呈现, 一个用于管理 UI.呈现线程有效地隐藏在后台运行,而 UI 线程则接收输入.处理事件.绘制屏幕 以及运行应用 ...
- .net程序员转行做手游开发经历(一)
从辞职到自己开发游戏也有几个月的时间了,游戏也已经在AppStore上线了,我觉得我有必要写点东西,算是留下的一些记忆,也可以和广大博友分享下自己的创业经历,这可能不是一篇成功的创业经历,因为故事还在 ...
- “奥特曼攻打小怪兽”java学习打怪升级第一步
---恢复内容开始--- 练习:回合制对战游戏:奥特曼和小怪兽进行PK,直到一方的血量为0时结束战斗,输出谁胜利了! 不难看出场景中有两个对象:”奥特曼“这一对象抽象为”Ao"类: ...
- arguments.callee 调用自身 caller,callee,apply and call
一.Arguments该对象代表正在执行的函数和调用他的函数的参数.[function.]arguments[n]参数function :选项.当前正在执行的 Function 对象的名字.n :选项 ...