4408: [Fjoi 2016]神秘数

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 475  Solved: 287
[Submit][Status][Discuss]

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<=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

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

Source

鸣谢yyh上传

Solution

这道题挺好的思路。

首先考虑在集合中已经选出$k$个数的时候,再加入第$k+1$个数的情况。

显然有当$a_{k+1}>\sum ^{k}_{i=1} a_{k} +1$时,$ans=\sum ^{k}_{i=1} a_{k}+1$

否则显然这个这些数能组合出的范围扩大$a_{k+1}$

所以思路就是对于一个$ans$,求出$\sum ^{R}_{i=L} (a_{i}<ans) a_{i}$,如果这些数能组合到$ans$,那么这个$ans$只能扩大,所以把$ans$扩大到$\sum ^{R}_{i=L} (a_{i}<ans) a_{i} +1$继续做,否则得到神秘数。

所以支持这样做的还是利用可持久化线段树求出。

但是这样的复杂度还是比较暴力的,不过题目中说了$\sum a_{i}<10^{9}$所以复杂度最坏是 $O(MlogNlog10^{9})$

话说这题被xyx秒了....

Code

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
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;
}
#define MAXN 100010 int N,M,a[MAXN]; namespace PrTree{
int root[MAXN],sum[MAXN*20],lson[MAXN*20],rson[MAXN*20],sz;
inline void Insert(int l,int r,int &x,int last,int pos,int val)
{
x=++sz;
lson[x]=lson[last],rson[x]=rson[last];
sum[x]=sum[last]+val;
if (l==r) return;
int mid=(l+r)>>1;
if (pos<=mid) Insert(l,mid,lson[x],lson[last],pos,val);
else Insert(mid+1,r,rson[x],rson[last],pos,val);
}
inline int Query(int l,int r,int L,int R,int x,int y)
{
if (L>R) return 0;
if (L<=l && R>=r) return sum[y]-sum[x];
int mid=(l+r)>>1,re=0;
if (L<=mid) re+=Query(l,mid,L,R,lson[x],lson[y]);
if (R>mid) re+=Query(mid+1,r,L,R,rson[x],rson[y]);
return re;
}
}using namespace PrTree; int ls[MAXN]; int main()
{
N=read();
for (int i=1; i<=N; i++) ls[i]=a[i]=read(); sort(ls+1,ls+N+1); int tot=unique(ls+1,ls+N+1)-ls-1; for (int i=1; i<=N; i++) a[i]=lower_bound(ls+1,ls+tot+1,a[i])-ls; for (int i=1; i<=N; i++) PrTree::Insert(1,tot,root[i],root[i-1],a[i],ls[a[i]]); M=read();
while (M--) {
int l=read(),r=read();
int ans=1,up,pos;
while (1) {
pos=upper_bound(ls+1,ls+tot+1,ans)-ls-1;
if (ans<=(up=PrTree::Query(1,tot,1,pos,root[l-1],root[r])))
ans=up+1;
else break;
}
printf("%d\n",ans);
}
return 0;
}

  

【BZOJ-4408】神秘数 可持久化线段树的更多相关文章

  1. (bzoj4408)[FJOI2016]神秘数(可持久化线段树)

    (bzoj4408)[FJOI2016]神秘数(可持久化线段树) bzoj luogu 对于一个区间的数,排序之后从左到右每一个数扫 如果扫到某个数a时已经证明了前面的数能表示[1,x],那么分情况: ...

  2. Bzoj 4408: [Fjoi 2016]神秘数 可持久化线段树,神题

    4408: [Fjoi 2016]神秘数 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 177  Solved: 128[Submit][Status ...

  3. BZOJ 4408: [Fjoi 2016]神秘数 可持久化线段树

    4408: [Fjoi 2016]神秘数 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=4408 Description 一个可重复数字集 ...

  4. BZOJ 4408 FJOI2016 神秘数 可持久化线段树

    Description 一个可重复数字集合S的神秘数定义为最小的不能被S的子集的和表示的正整数.例如S={1,1,1,4,13},1 = 12 = 1+13 = 1+1+14 = 45 = 4+16 ...

  5. 51Nod 1175 区间中第K大的数 (可持久化线段树+离散)

    1175 区间中第K大的数 基准时间限制:1 秒 空间限制:131072 KB 分值: 160 难度:6级算法题   一个长度为N的整数序列,编号0 - N - 1.进行Q次查询,查询编号i至j的所有 ...

  6. bzoj 2653 二分答案+可持久化线段树

    首先离散化,然后我们知道如果对于一个询问的区间[l1,r1],[l2,r2],我们二分到一个答案x,将[l1,r2]区间中的元素大于等于x的设为1,其余的设为-1,那么如果[l1,r1]的最大右区间和 ...

  7. bzoj 2653 middle (可持久化线段树)

    middle Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 1981  Solved: 1097[Submit][Status][Discuss] D ...

  8. BZOJ 3542 [Poi2014]Couriers ——可持久化线段树

    [题目分析] 查找区间内出现次数大于一半的数字. 直接用主席树,线段树上维护区间大小,由于要求出现次数大于一半,每到一个节点可以分治下去. 时间复杂度(N+Q)logN [代码] #include & ...

  9. BZOJ 4408 神秘数

    题解同各神犇的方法... #include<iostream> #include<cstdio> #include<cstring> #include<alg ...

随机推荐

  1. POJ - 1753 Flip Game(状压枚举)

    https://vjudge.net/problem/POJ-1753 题意 4*4的棋盘,翻转其中的一个棋子,会带动邻接的棋子一起动.现要求把所有棋子都翻成同一种颜色,问最少需要几步. 分析 同一个 ...

  2. CSS规范 - 命名规则--(来自网易)

    使用类选择器,放弃ID选择器 ID在一个页面中的唯一性导致了如果以ID为选择器来写CSS,就无法重用. NEC特殊字符:"-"连字符 "-"在本规范中并不表示连 ...

  3. html5 canvas 垂直渐变描边

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  4. leaflet-velocity 参数

    本文地址: https://www.cnblogs.com/veinyin/p/10769611.html  leaflet-velocity 是 leaflet 绘制风场的一个插件,其控制参数如下所 ...

  5. CSUST 1506 ZZ的计算器 模拟题

    题目描述:实现一个计算器,可以进行任意步的整数以内的加减乘除运算,运算符号只有+.-.*./,求出结果. 解题报告:一个可以说麻烦的模拟题,我们可以这样,输入以字符串的形式输入,然后将输入先做一遍预处 ...

  6. kali更新失败

    今天更新kali时失败,出现如下问题: root@kali:~# apt-get update Get: http://mirrors.aliyun.com/kali kali-rolling InR ...

  7. vs-code 配置

    vs-code 快键键 命令面板 ctrl+shift+p vs-code 相关插件 AutoFileName Chinese (Simplified) Language Pack for Visua ...

  8. fish(自动推荐命令;语法高亮等)

    Fish 是 Linux/Unix/Mac OS 的一个命令行 shell,有一些很好用的功能. 自动推荐 VGA 颜色 完美的脚本支持 基于网页的配置 帮助文档自动补全 语法高亮 以及更多 自动推荐 ...

  9. 为你详细解读HTTP请求头的具体含意

    当我们打开一个网页时,浏览器要向网站服务器发送一个HTTP请求头,然后网站服务器根据HTTP请求头的内容生成当次请求的内容发送给浏览器.你明白HTTP请求头的具体含意吗?下面一条条的为你详细解读,先看 ...

  10. 开启@EnableRedisHttpSession

    sessionId=569662ce-c6d5-42a9-a94b-c9df826df716 1800秒后失效 sessionId=23913542-9b5f-4699-8a87-1023b57f5f ...