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. java整理的一些面试资料

    平时逛博客的时候收集了一些认为不错的java面试题  以后跳槽的时候可以来这里刷一刷 1:后端技术精选 https://www.cnblogs.com/javazhiyin/tag/Java面试题/

  2. HDU 1863 畅通工程 最下生成树问题

    题目描述:给出图,要你求是否存在最小生成树,如果存在,要求输出最小权值和,如果不存在,输出? 解题报告:又是一个最裸的克鲁斯卡尔,并且要判断是否存在最小生成树的问题.废话不多说,给个短代码: #inc ...

  3. JS中字符串那些事~

    1:字符串 JS中的任何数据类型都可以当作对象来看.所以string既是基本数据类型,又是对象. 2:声明字符串 var sStr = ‘字符串’;(常用) var oStr = new String ...

  4. spring如何管理mybatis(二) ----- SqlSession的线程安全性

    在之前的文章中我们了解到最终的数据库最终操作是走的代理类的方法: @Override public Object invoke(Object proxy, Method method, Object[ ...

  5. asp.net mvc 根据路由生成正确的url

    假设存在这样一段路由配置: routes.MapRoute( name: "ProductList1_01", url: "pl/{bigSortId}_{smallSo ...

  6. 3.微信公众号开发:配置与微信公众平台服务器交互的URL接口地址

    微信开发基本原理: 1.首先有3个对象 分别是微信用户端 微信公众平台服务器 开发者服务器(也就是放自己代码的服务器) 三者间互相交互 2.微信公众平台服务器 充当中间者角色 (以被动回复消息为例) ...

  7. Comparable和Comparator的区别&Collections.sort的两种用法

    在Java集合的学习中,我们明白了: 看到tree,可以按顺序进行排列,就要想到两个接口.Comparable(集合中元素实现这个接口,元素自身具备可比性),Comparator(比较器,传入容器构造 ...

  8. spring的事务控制

    1.事务介绍 (1)特性:ACID Atomicity(原子性):事务中的所有操作要么全做要么全不做 Consistency(一致性):事务执行的结果使得数据库从一个一致性状态转移到另一个一致性状态 ...

  9. centos6.8安装mysql5.6【转】

    首先先要去看看本机有没有默认的mysql, 本地默认有的,我们应先卸载,在安装新的这个逻辑. rpm -qa | grep mysql 我本机默认安装的mysql5.1.73 下一步删除 rpm -e ...

  10. IE WebBrowser内核设置

    public class IEVersion { /// <summary> /// IE WebBrowser内核设置 /// </summary> public stati ...