神秘数
来源:互联网 发布:最好的网络验证 编辑:程序博客网 时间:2024/04/19 23:42
神秘数
时间限制: 1 Sec 内存限制: 256 MB
题目描述
一个可重复数字集合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,求由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
【数据范围】
对于10%的数据点,n,m <= 10
对于30%的数据点,n,m <= 1000
对于60%的数据点,n,m <= 50000
对于100%的数据点,n,m <= 100000,∑a[i] <= 109
来源
FJOI2016
题解
写在前面:就是这道题害我省选爆零,直接退役。
进入正题:
考虑一段数列,如何计算它的神秘数?
将其排序,若sum[i-1]>s[i]+1,那么神秘数即为sum[i-1]。
对于一组询问,每次暴力更新区间内>=sum+1的数,当出现斐波那契数列时达到上界。
用一棵主席树维护区间和。
注意细节,记得对拍,不然就要像我一样爆零退役了。
代码
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<string> #include<cmath> #include<algorithm> #define N 100010#define inf 2100000000using namespace std;int n,m,tot,s[N],id[N],num[N],rt[N],cnt;struct node{int lc,rc,sum;}t[N*18];bool cmp(const int &a,const int &b){return s[a]<s[b];}class functional_seg_tree{ public: void modify(int &x,int pre,int l,int r,int des,int val) { x=++cnt;t[x]=t[pre];t[x].sum+=val; if(l==r)return; int mid=l+r>>1; if(des<=mid)modify(t[x].lc,t[pre].lc,l,mid,des,val); else modify(t[x].rc,t[pre].rc,mid+1,r,des,val); } int qry(int x,int l,int r,int ql,int qr) { if(ql<=l&&r<=qr)return t[x].sum; int mid=l+r>>1,res=0; if(ql<=mid)res+=qry(t[x].lc,l,mid,ql,qr); if(qr>mid)res+=qry(t[x].rc,mid+1,r,ql,qr); return res; }}T;int main(){ int a,b; scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%d",&s[i]),id[i]=i; sort(id+1,id+n+1,cmp); for(int i=1;i<=n;i++) { num[++tot]=s[id[i]]; T.modify(rt[tot],rt[tot-1],1,n,id[i],s[id[i]]); while(s[id[i]]==s[id[i+1]]) i++,T.modify(rt[tot],rt[tot],1,n,id[i],s[id[i]]); } scanf("%d",&m); while(m--) { scanf("%d%d",&a,&b); int ans=0,pre=0; while(1) { int l=1,r=tot,pos=0; while(r-l>1) { int mid=l+r>>1; if(num[mid]<=ans+1)l=mid; else r=mid-1; } pos=num[r]<=ans+1?pos=r:l; if(pos==pre)break; ans=T.qry(rt[pre=pos],1,n,a,b); } printf("%d\n",ans+1); } return 0;}
0 0
- 神秘数
- [算法] 神秘数
- BZOJ4408: [Fjoi 2016]神秘数
- BZOJ4408: [Fjoi 2016]神秘数
- BZOJ4408: [Fjoi 2016]神秘数
- 银行"神秘账户"存款数亿
- bzoj 4408: [FJOI2016]神秘数 主席树
- [BZOJ4408][FJOI2016]神秘数(主席树)
- 神秘
- BZOJ4408: [Fjoi 2016]神秘数&&BZOJ4299: Codechef FRBSUM
- bzoj 4408: [Fjoi 2016]神秘数 (主席树)
- bzoj 4408 [Fjoi 2016]神秘数 主席树
- [可持久化线段树] [bzoj4408] [Fjoi2016]神秘数
- 其实回调函数并不神秘 C/C++中回调函数初探
- 其实回调函数并不神秘 C/C++中回调函数初探
- 抛出了无数的Exception,但是Exception到底是啥?解开Exception的神秘面纱...
- 4408: [Fj Winter Camp 2016]神秘数&&4299: Codechef FRBSUM|主席树
- [BZOJ4408][Fjoi 2016]神秘数(可持久化线段树)
- js实现svg绘图的时针
- 析构函数不为虚函数时的处理方式
- 操作系统课程设计2 编写Linux bash脚本
- C/CPP点滴积累—程序内存
- 使用CALayer的Mask实现注水动画效果
- 神秘数
- 1001. 害死人不偿命的(3n+1)猜想
- unity3d事件函数整理,事件,回调函数,消息处理
- 消息交互JMS(六)
- LA 4413 梅涅劳斯定理
- 实现一边录音一边转化为文字的功能
- 大规模机器学习 机器学习基础(9)
- getAttribute和getParameter的区别
- PS进修第一篇