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,即[1,k]中的所有数都能取到,现在加入了一个数x。

若x <= k+1,则能取到的最大值为k+x,神秘数为k+x+1

若x > k+1,则能取到的最大值仍为k,神秘数为k+1

对于一个询问(l,r),设当前神秘数为k,若Σai >= k(ai <= k && i∈[l,r]),则说明k仍能增大,否则,神秘数即为k。

而求前缀和,可以用可持久化线段树来解决。

每次寻找,k至少增加一倍,每次求前缀和是logn,总的时间复杂度是O(Q*log1e92)

Code

 #include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <algorithm> using namespace std; #define REP(i, a, b) for (int i = (a), i##_end_ = (b); i <= i##_end_; ++i)
typedef long long LL;
const int maxn = 1e5+;
int n, a[maxn];
struct Node
{
LL sum; int ls, rs;
Node() { sum = ls = rs = ; }
}t[maxn*];
int rt[maxn], t_cnt, mx_a; void pushup(Node &x) { x.sum = t[x.ls].sum+t[x.rs].sum; } void update(int now_rt, int las_rt, int l, int r, int x)
{
if (l == r)
{
t[now_rt].sum = t[las_rt].sum+x;
return ;
}
int mid = (l+r)>>;
if (x <= mid)
{
t[now_rt].rs = t[las_rt].rs, t[now_rt].ls = ++t_cnt;
update(t[now_rt].ls, t[las_rt].ls, l, mid, x);
}
else
{
t[now_rt].ls = t[las_rt].ls, t[now_rt].rs = ++t_cnt;
update(t[now_rt].rs, t[las_rt].rs, mid+, r, x);
}
pushup(t[now_rt]);
} int query(int rt_1, int rt_2, int l, int r, int x)
{
if (l > x) return ;
if (r <= x) return t[rt_2].sum-t[rt_1].sum;
int mid = (l+r)>>;
int ret = query(t[rt_1].ls, t[rt_2].ls, l, mid, x);
if (x > mid) ret += query(t[rt_1].rs, t[rt_2].rs, mid+, r, x);
return ret;
} int calc(int l, int r)
{
int ret = , temp = ;
while ((temp = query(rt[l-], rt[r], , mx_a, ret)) >= ret) ret = temp+;
return ret;
} int main()
{
scanf("%d", &n);
REP(i, , n) scanf("%d", &a[i]), mx_a = max(mx_a, a[i]);
REP(i, , n) update(rt[i] = ++t_cnt, rt[i-], , mx_a, a[i]);
int Q, l, r;
scanf("%d", &Q);
while (Q --)
{
scanf("%d %d", &l, &r);
printf("%d\n", calc(l, r));
}
return ;
}

【Codechef FRBSUM】【FJOI2016】【BZOJ4299】【BZOJ 4408】 可持久化线段树的更多相关文章

  1. bzoj 3123 可持久化线段树启发式合并

    首先没有连边的操作的时候,我们可以用可持久化线段树来维护这棵树的信息,建立权值可持久化线段树,那么每个点继承父节点的线段树,当询问为x,y的时候我们可以询问rot[x]+rot[y]-rot[lca( ...

  2. bzoj 3207 可持久化线段树

    首先因为固定询问长度,所以我们可以将整个长度为n的数列hash成长度为n-k+1的数列,每次询问的序列也hash成一个数,然后询问这个数是不是在某个区间中出现过,这样我们可以根据初始数列的权值建立可持 ...

  3. bzoj 3524 可持久化线段树

    我们可以先离散化,然后建立权值的可持久化线段树,记录每个数出现的次数,对于区间询问直接判断左右儿子的cnt是不是大于(r-k+1)/2,然后递归到最后一层要是还是大于就有,否则不存在. 反思:挺简单一 ...

  4. bzoj 3207 可持久化线段树+hash

    这道题要看出来这个做法还是比较容易说一下细节 1.因为要用hash的区间值域来建树,而hash为了不冲突要开的很大,所以值域就会比较的大,不过这道题好的一点是没有修改,所以直接离散一下就会小很多 2. ...

  5. BZOJ 2588: Spoj 10628. Count on a tree-可持久化线段树+LCA(点权)(树上的操作) 无语(为什么我的LCA的板子不对)

    2588: Spoj 10628. Count on a tree Time Limit: 12 Sec  Memory Limit: 128 MBSubmit: 9280  Solved: 2421 ...

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

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

  7. BZOJ 3221: [Codechef FEB13] Obserbing the tree树上询问( 可持久化线段树 + 树链剖分 )

    树链剖分+可持久化线段树....这个一眼可以看出来, 因为可持久化所以写了标记永久化(否则就是区间修改的线段树的持久化..不会), 结果就写挂了, T得飞起...和管理员拿数据调后才发现= = 做法: ...

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

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

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

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

随机推荐

  1. centos6.x下安装maven

    转自:http://www.centoscn.com/image-text/install/2014/0507/2923.html 1.下载maven包首先从官网上 http://maven.apac ...

  2. Java SSM框架之MyBatis3(八)MyBatis之动态SQL

    前言: mybatis框架中最具特色的便是sql语句中的自定义,而动态sql的使用又使整个框架更加灵活. 创建User表 /*Table structure for table `user` */ D ...

  3. 【转】VTL-vm模板的变量用法

    http://www.cnblogs.com/zengxlf/archive/2009/05/06/1451004.html 加载foot模块页 #parse("foot.vm") ...

  4. shell ssh 批量执行

    ssh 批量执行命令 #版本1 #!/bin/bash while read line do Ip=`echo $line|awk '{print $1}'` Passwd=`echo $line|a ...

  5. HDU 2112 HDU Today 最短路

    题目描述: Problem Description 经过锦囊相助,海东集团终于度过了危机,从此,HDU的发展就一直顺风顺水,到了2050年,集团已经相当规模了,据说进入了钱江肉丝经济开发区500强.这 ...

  6. [译]How To Use the Linux Auditing System on CentOS 7

    本文是How To Use the Linux Auditing System on CentOS 7的中文版,翻译不到之处,还请指出和多多包涵.本文并不会完全遵从原文的一些格式,而是加入自己学习的理 ...

  7. 转载 你不知道的super

    http://funhacks.net/2016/11/09/super/ super仅被用于新式类 在类的继承中,如果重定义某个方法,该方法会覆盖父类的同名方法,但有时,我们希望能同时实现父类的功能 ...

  8. weblogica

  9. Identical Binary Tree

    Check if two binary trees are identical. Identical means the two binary trees have the same structur ...

  10. 使用netperf测试网络性能

    1.安装netperf 1)获取netperf安装包 netperf-2.7.0.tar.bz2 2)解压到本地目录 3)进入netperf-2.7.0,执行:./configure 4)编译执行:m ...