FJOI2016 神秘数
题目大意
给定长为$N$一个序列,每次询问一个区间,求最小的不能表示为由区间内若干个(可以是$0$个)数的和的非负整数。
考虑一个可重集合$S$,设抽取$S$中若干个数相加无法得到的最小非负整数为$Ans_S$
显然$Ans_{\emptyset}=1$
当加入一个元素$x$时
当$x>Ans_S$时,原先的$Ans_S$仍然无法凑出来,所以答案不变
当$x\leq Ans_S$时,原先的$0,1...Ans_S-1$可表示为$x,x+1...Ans_S-1+x$由于$x\leq Ans_S-1$
所以$S$加入$x$后得到的$K$一可以表示$0,1...Ans_S+x-1$,而$Ans_S+x$仍然无法凑出来
所以$Ans_K=Ans_S+x$
但是这样直接做还是会$TLE$,因为每次询问得把区间扫一遍。
我们想一个很暴力的优化。
设当前答案为$ans$,你已经加上了区间内小于等于$last$的数的和。
由于答案已经达到了$ans$,我们求出$sum=$区间内满足$last<x\leq ans$的所有$x$的和。
若$sum=0$,则答案已经不再影响,直接停止就好,否则我们令$last=ans,ans=ans+sum$即可。
初始时$last=0,ans=1$。
这看起来很暴力,但是其中对于所有的若$sum>0$,则一定有$sum>last$,所以每两次操作$last$至少扩大一倍,而所有数的总和又是固定的,所以对于每一次询问$ans$只会进行$\log$级别次数的增加。
区间求一定值域内的和,用可持久化线段树维护即可。
复杂度$O(N\log(\sum A_i)+M\log^2(\sum A_i))$
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#define LL long long
#define M 120000
#define mid ((l+r)>>1)
#define MAXN 1000000002
using namespace std;
int read(){
int nm=0,fh=1; char cw=getchar();
for(;!isdigit(cw);cw=getchar()) if(cw=='-') fh=-fh;
for(;isdigit(cw);cw=getchar()) nm=nm*10+(cw-'0');
return nm*fh;
}
int n,m,sum[M*32],L[M*32],R[M*32],rt[M],cnt;
void write(int x){if(x>9) write(x/10); putchar(x-(x/10)*10+'0');}
void ins(int &x,int pre,int l,int r,int pos){
x=++cnt,L[x]=L[pre],R[x]=R[pre];
sum[x]=sum[pre]+pos; if(l==r) return;
if(pos<=mid) ins(L[x],L[pre],l,mid,pos);
else ins(R[x],R[pre],mid+1,r,pos);
}
int qry(int now,int pre,int l,int r,int ls,int rs){
if(sum[now]==sum[pre]||r<ls||rs<l) return 0;
if(ls<=l&&r<=rs) return sum[now]-sum[pre];
return qry(L[now],L[pre],l,mid,ls,rs)+qry(R[now],R[pre],mid+1,r,ls,rs);
}
int main(){
n=read();
for(int i=1;i<=n;i++) m=read(),ins(rt[i],rt[i-1],1,MAXN,m);
for(int T=read(),last=0,ans=1;T;T--,last=0,ans=1){
int ls=read()-1,rs=read(),now=0;
while(true){
now=qry(rt[rs],rt[ls],1,MAXN,last+1,ans);
if(!now) break; last=ans,ans+=now;
} write(ans),putchar('\n');
}
return 0;
}
FJOI2016 神秘数的更多相关文章
- 【BZOJ4408】[FJOI2016]神秘数(主席树)
[BZOJ4408][FJOI2016]神秘数(主席树) 题面 BZOJ 洛谷 题解 考虑只有一次询问. 我们把所有数排个序,假设当前可以表示出的最大数是\(x\). 起始\(x=0\). 依次考虑接 ...
- 【LG4587】[FJOI2016]神秘数
[LG4587][FJOI2016]神秘数 题面 洛谷 题解 首先我们想一想暴力怎么做 对于一段区间\([l,r]\) 我们先将它之间的数升序排序 从左往右扫, 设当前我们可以表示出的数为\([1,x ...
- (bzoj4408)[FJOI2016]神秘数(可持久化线段树)
(bzoj4408)[FJOI2016]神秘数(可持久化线段树) bzoj luogu 对于一个区间的数,排序之后从左到右每一个数扫 如果扫到某个数a时已经证明了前面的数能表示[1,x],那么分情况: ...
- [bzoj4408][Fjoi2016]神秘数
Description 一个可重复数字集合$S$的神秘数定义为最小的不能被$S$的子集的和表示的正整数. 例如$S={1,1,1,4,13}$, $1=1$, $2=1+1$, $3=1+1+1$, ...
- [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]\)都是可以表示出来 ...
- BZOJ4299 & CC FRBSUM:ForbiddenSum & BZOJ4408 & 洛谷4587 & LOJ2174:[FJOI2016]神秘数——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=4299 https://www.lydsy.com/JudgeOnline/problem.php? ...
- BZOJ 4408 FJOI2016 神秘数 可持久化线段树
Description 一个可重复数字集合S的神秘数定义为最小的不能被S的子集的和表示的正整数.例如S={1,1,1,4,13},1 = 12 = 1+13 = 1+1+14 = 45 = 4+16 ...
- 洛谷 P4587 [FJOI2016]神秘数
大鸽子 llmmkk 正在补8.3号咕掉的题 时隔两个月,再看到这道题,我又是一脸懵,这种思维的培养太重要了 链接: P4587 题意: 给出 \(n\) 个点的序列,\(m\) 次询问区间神秘数. ...
- Luogu4587 [FJOI2016]神秘数
题目大意:给定一个长度为$n$的正整数序列$a_i$,$m$次询问,每次询问$[l,r]$,求最小的无法表示成$a_l,a_{l+1},\ldots,a_r$的子集之和的正整数. 数据范围:$1\le ...
随机推荐
- Android SQLite基本用法
SQLite简介 Google为Andriod的较大的数据处理提供了SQLite,他在数据存储.管理.维护等各方面都相当出色,功能也非常的强大.SQLite具备下列特点: 1.轻量级 使用 SQLit ...
- centos7.0 安转mysql5.7
安装mysql5.7需要boost依赖包groupadd mysql useradd -r -g mysql -s /bin/false mysql cmake . -DCMAKE_INSTALL_P ...
- spring工作原理理解
spring的工作原理 spring是作为一个容器存在的框架,可以加载spring web,spring mvc,spring orm,sprong aop,spring dao等框架和模块,其主要核 ...
- Storm编程模型及Worker通信机制
1.编程模型 2.Worker通信机制
- HBase核心技术点
表的rowkey设计核心思想: 依据rowkey查询最快 对rowkey进行范围查询range 前缀匹配 预分区创建的三种方式 create 'ns1:t1', 'f1', SPLITS => ...
- Map集合按value的大小排序
public static void main(String[] args) { Map<String, Integer> map = new HashMap<String, Int ...
- git生成public key
1 配置user name和email git config --global user.name "xxx" git config --global user.email &qu ...
- 洛谷 2216 [HAOI2007]理想的正方形
题目戳这里 一句话题意 给你一个a×b的矩形,求一个n×n的子矩阵,矩阵里面的最大值和最小值之差最小. Solution 这个题目许多大佬都是单调队列,但是我不是很会,只好用了比较傻逼的方法: 首先我 ...
- JVM类加载器
系统中的类加载器 1.BootStrap ClassLoader a.启动ClassLoader b.加载rt.jar 2.Extension ClassLoader a.扩展ClassLoader ...
- 11.23 Eclipse
一.Eclipse Workspace File-->Switch Workspace 编译环境:Window -- Preferences – Java - Compiler 运行环境:Win ...