4299: Codechef FRBSUM

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 550  Solved: 351
[Submit][Status][Discuss]

Description

数集S的ForbiddenSum定义为无法用S的某个子集(可以为空)的和表示的最小的非负整数。
例如,S={1,1,3,7},则它的子集和中包含0(S’=∅),1(S’={1}),2(S’={1,1}),3(S’={3}),4(S’={1,3}),5(S' = {1, 1, 3}),但是它无法得到6。因此S的ForbiddenSum为6。
给定一个序列A,你的任务是回答该数列的一些子区间所形成的数集的ForbiddenSum是多少。

Input

输入数据的第一行包含一个整数N,表示序列的长度。
接下来一行包含N个数,表示给定的序列A(从1标号)。
接下来一行包含一个整数M,表示询问的组数。
接下来M行,每行一对整数,表示一组询问。

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%的数据,1≤N,M≤100000,1≤A_i≤10^9,1≤A_1+A_2+…+A_N≤10^9。

Source

[Fjoi 2016]神秘数

时间限制:10s      空间限制:128MB

题目描述

一个可重复数字集合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]所构成的可重复数字集合的神秘数。


输入格式

第一行一个整数n,表示数字个数。
第二行n个整数,从1编号。
第三行一个整数m,表示询问个数。
以下m行,每行一对整数l,r,表示一个询问。


输出格式

对于每个询问,输出一行对应的答案。


样例输入

5
1 2 4 9 10
5
1 1
1 2
1 3
1 4
1 5

样例输出

2
4
8
8
8

提示

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


题目来源

鸣谢yyh上传

这两题实际上是双倍经验,但我做了两遍且两遍都不会做。。

主席树非常巧妙的应用,对于一个集合S,如果S中的数可以凑出mx,那么如果向集合S中新添加一个数x,若x<=mx+1,那么加入x后S可以凑出0~mx+x的所有数,但如果x>mx+1,则x对扩大可凑出的数的范围没有作用。

这样这题就可做了,设当前已知的一定能凑出来的范围是0~mx(mx初值为0),用权值主席树快速求出区间[l,r]中所有不大于mx+1的数的和作为新的mx,如果发现mx没有增大说明mx+1就是不可凑出的数。

复杂度O(nlog^2n)

BZOJ4299:

 #include<cstdio>
#include<algorithm>
#define rep(i,l,r) for (int i=l; i<=r; i++)
using namespace std; const int N=;
int n,m,nd,l,r,mx,lst,a[N],rt[N],L[N*],R[N*],tot[N*]; void ins(int x,int &y,int l,int r,int k){
y=++nd; L[y]=L[x]; R[y]=R[x]; tot[y]=tot[x]+k;
if (l==r) return; int mid=(l+r)>>;
if (k<=mid) ins(L[x],L[y],l,mid,k); else ins(R[x],R[y],mid+,r,k);
} int que(int x,int y,int l,int r,int k){
if (l==r) return tot[y]-tot[x];
int mid=(l+r)>>;
if (k<=mid) return que(L[x],L[y],l,mid,k);
else return tot[L[y]]-tot[L[x]]+que(R[x],R[y],mid+,r,k);
} int main(){
scanf("%d",&n);
rep(i,,n) scanf("%d",a+i),ins(rt[i-],rt[i],,1e9,a[i]);
for (scanf("%d",&m); m--; ){
scanf("%d%d",&l,&r); mx=lst=;
while (){
mx=que(rt[l-],rt[r],,1e9,mx+);
if (lst==mx) break; lst=mx;
}
printf("%d\n",lst+);
}
return ;
}

BZOJ4408:

 #include<cstdio>
#include<algorithm>
#define rep(i,l,r) for (int i=l; i<=r; i++)
using namespace std; const int N=,M=;
int n,m,l,r,nd,tot,t,ans,a[N],num[N],rt[N],sm[M],ls[M],rs[M]; int find(int x){
int L=,R=tot+;
while (L+<R){
int mid=(L+R)>>;
if (x<num[mid]) R=mid; else L=mid;
}
return L;
} void ins(int y,int &x,int L,int R,int pos,int k){
sm[x=++nd]=sm[y]+k; ls[x]=ls[y]; rs[x]=rs[y];
if (L==R) return;
int mid=(L+R)>>;
if (pos<=mid) ins(ls[y],ls[x],L,mid,pos,k); else ins(rs[y],rs[x],mid+,R,pos,k);
} int que(int l,int r,int k){
int L=,R=tot,mid,ans=; l=rt[l-]; r=rt[r];
while (L<R){
mid=(L+R)>>;
if (k<=mid) R=mid,l=ls[l],r=ls[r];
else L=mid+,ans+=sm[ls[r]]-sm[ls[l]],l=rs[l],r=rs[r];
}
return ans+sm[r]-sm[l];
} int main(){
freopen("bzoj4408.in","r",stdin);
freopen("bzoj4408.out","w",stdout);
scanf("%d",&n);
rep(i,,n) scanf("%d",&a[i]),num[i]=a[i]; n++;
sort(num+,num+n+); tot=unique(num+,num+n+)-num-;
rep(i,,n) a[i]=find(a[i]);
rep(i,,n) ins(rt[i-],rt[i],,tot,a[i],num[a[i]]);
for (scanf("%d",&m); m--; ){
scanf("%d%d",&l,&r);
for (ans=; ; ans=t+){
t=que(l,r,find(ans));
if (t<ans) break;
}
printf("%d\n",ans);
}
return ;
}

[BZOJ4408&&BZOJ4299][FJOI2016 && Codechef]神秘数&&FRBSUM(主席树)的更多相关文章

  1. 【BZOJ4408】[FJOI2016]神秘数(主席树)

    [BZOJ4408][FJOI2016]神秘数(主席树) 题面 BZOJ 洛谷 题解 考虑只有一次询问. 我们把所有数排个序,假设当前可以表示出的最大数是\(x\). 起始\(x=0\). 依次考虑接 ...

  2. BZOJ4408: [Fjoi 2016]神秘数【主席树好题】

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

  3. BZOJ4408 [Fjoi 2016]神秘数 【主席树】

    题目链接 BZOJ4408 题解 假如我们已经求出一个集合所能凑出连续数的最大区间\([1,max]\),那么此时答案为\(max + 1\) 那么我们此时加入一个数\(x\),假若\(x > ...

  4. 洛谷P4587 [FJOI2016]神秘数(主席树)

    题面 洛谷 题解 考虑暴力,对于询问中的一段区间\([l,r]\),我们先将其中的数升序排序,假设当前可以表示出\([1,k]\)目前处理\(a_i\),假如\(a_i>k+1\),则答案就是\ ...

  5. [Bzoj4408]神秘数(主席树)

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

  6. 220722 T4 求和 /P4587 [FJOI2016]神秘数 (主席树)

    好久没打主席树了,都忘了怎么用了...... 假设我们选了一些数能构成[0,x]范围内的所有值,下一个要加的数是k(k<=x+1),那么可以取到[0,x+k]内的所有取值,所以有一种做法: 对于 ...

  7. 【洛谷4587】 [FJOI2016]神秘数(主席树)

    传送门 BZOJ 然而是权限题 洛谷 Solution 发现题目给出的一些规律,emm,如果我们新凑出来的一个数,那么后面一个数一定是\(sum+1\). 于是就可以主席树随便维护了! 代码实现 #i ...

  8. 【BZOJ4408】[Fjoi 2016]神秘数 主席树神题

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

  9. 「FJOI2016」神秘数 解题报告

    「FJOI2016」神秘数 这题不sb,我挺sb的... 我连不带区间的都不会哇 考虑给你一个整数集,如何求这个神秘数 这有点像一个01背包,复杂度和值域有关.但是你发现01背包可以求出更多的东西,就 ...

随机推荐

  1. 【HDU】6110 路径交(2017百度之星) 线段树+RMQ-LCA+树链的交

    [题目]2017"百度之星"程序设计大赛 - 初赛(A) [题意]给定n个点的带边权树,m条编号1~m的路径,Q次询问编号区间[L,R]所有链的交集的长度.n<=500000 ...

  2. 20155335俞昆《Java程序设计》第五周总结

    #  20155335    <Java程序设计>第五周学习总结 ##  教材学习内容总结 ##  教材学习中的问题和解决过程 对于异常处理,程序中总有意想不到的状况所引发的的错误,Jav ...

  3. 彻底解决mysql中文乱码

    mysql是我们项目中非常常用的数据型数据库.但是因为我们需要在数据库保存中文字符,所以经常遇到数据库乱码情况.下面就来介绍一下如何彻底解决数据库中文乱码情况. 1.中文乱码 1.1.中文乱码 cre ...

  4. php审计学习:xdcms2.0.8注入

    注入点Fields: 注册页面会引用如下方法: $fields 变量是从 $fields=$_POST['fields']; 这里获取, 在代码里没有过滤. 打印 fields 数据查看: 从代码上看 ...

  5. PHP中的 get_magic_quotes_runtime

    get_magic_quotes_runtime() 获得外部文件及数据库资料时是否进行转义 set_magic_quotes_runtime(1); 临时设置获得外部文件及数据库资料时是否进行转义 ...

  6. 72.xilinx vivado zynq vdma仿真及应用详解(一)

    很多人用zynq平台做视频图像开发,但是对vdma了解比较少,上手起来稍微有些困难,我针对这一现象,做了一个基于vivado和modelsim的仿真和应用测试工程,并写篇文章做些介绍,希望能对大家有帮 ...

  7. nvidia tx1使用记录--基本环境搭建

    前言 之前有专门写过一篇nvidia tk1使用记录--基本环境搭建,本以为自己有过tk1的经验后,在tx1上搭建和它一样的环境会轻车熟路,结果却是在nvidia tx1上花的时间居然比tk1还多.我 ...

  8. udhcpc命令

    要使用网络通讯,所以不可避免的要用到dhcp.理想的网络通讯方式是下面3种都要支持: 1,接入已有网络.这便要求可以作为dhcp客户端. 2,作为DHCP服务器,动态分配IP. 简单说下前2种情况. ...

  9. solr应用

    Solr是apache的顶级开源项目,它是使用java开发 ,基于lucene的全文检索服务器.Solr比lucene提供了更多的查询语句,而且它可扩展.可配置,同时它对lucene的性能进行了优化. ...

  10. 结构体对齐及#pragma详细解释

    在linux下c语言结构体对齐: 1.自然对齐 struct 是一种复合数据类型,其构成元素既可以是基本数据类型(如int.long.float 等)的变量,也可以是一些复合数据类型(如array.s ...