[JSOI2008]最大数 线段树解法
2017-03-07 21:19
351 查看
题目描述
现在请求你维护一个数列,要求提供以下两种操作:1、 查询操作。
语法:Q L
功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值。
限制:L不超过当前数列的长度。
2、 插入操作。
语法:A n
功能:将n加上t,其中t是最近一次查询操作的答案(如果还未执行过查询操作,则t=0),并将所得结果对一个固定的常数D取模,将所得答案插入到数列的末尾。
限制:n是整数(可能为负数)并且在长整范围内。
注意:初始时数列是空的,没有一个数。
--by luogu
https://daniu.luogu.org/problem/show?pid=1198
先把序列的空位建好线段树,初始序列是空的,就先建为极小值(注意她是负的),对每个A操作,就是在相应位置单点修改,对每个Q操作,就是查询相应的位置的区间最值
位置是什么呢?
发现只要记下当前序列的结尾就迎刃而解啦;
代码如下:
#include<cstdio> using namespace std; long long D,n,t; int tree[1000000]; int m,len; void build(int ,int ,int ); void change(int ,int, int ,int ); int MAX(int ,int ,int ,int ,int ); int main() { int i,j,k,l; char c; scanf("%d%d",&m,&D); build(1,m,1); for(i=1;i<=m;i++){ c=getchar(); while(c!='A'&&c!='Q') c=getchar(); if(c=='A'){ scanf("%lld",&n); n=(n+t)%D; change(1,m,1,len+1); len++; } if(c=='Q'){ scanf("%d",&l); t=MAX(1,m,1,len-l+1,len); printf("%lld\n",t); } } return 0; } void build(int l,int r,int nu){ if(l==r){ tree[nu]=-2147483600; return; } int mid=(l+r)>>1; build(l,mid,nu<<1);build(mid+1,r,nu<<1|1); tree[nu]=-2147483600; } void change(int l,int r,int nu,int x){ if(l==r){ tree[nu]=n; return ; } int mid=(l+r)>>1; if(x<=mid) change(l,mid,nu<<1,x); else change(mid+1,r,nu<<1|1,x); if(tree[nu<<1]>tree[nu<<1|1]) tree[nu]=tree[nu<<1]; else tree[nu]=tree[nu<<1|1]; } int MAX(int l,int r,int nu,int L,int R){ if(L<=l&&r<=R) return tree[nu]; int mid=(l+r)>>1; int Lmax=-2147483600,Rmax=-2147483600; if(L<=mid) Lmax=MAX(l,mid,nu<<1,L,R); if(R>=mid+1) Rmax=MAX(mid+1,r,nu<<1|1,L,R); if(Lmax>Rmax) return Lmax; return Rmax; }
话说代码真难看呵;
相关文章推荐
- BZOJ 1012[JSOI2008]最大数maxnumber (线段树解法)
- [luoguP1198][JSOI2008] 最大数(线段树 || 单调栈)
- HYSBZ 1012(JSOI 2008) 最大数maxnumber(线段树点更新)
- 洛谷P1198 [JSOI2008]最大数(线段树)
- bzoj1012 [JSOI2008]最大数(单调栈+二分/线段树)
- bzoj-1012 1012: [JSOI2008]最大数maxnumber(线段树)
- 【JSOI2008】最大数 线段树
- BZOJ 1012 [JSOI2008]最大数maxnumber【线段树】
- BZOJ 1012: [JSOI2008]最大数maxnumber【线段树||单调栈】
- [JSOI2008]最大数 --线段树
- [BZOJ] 1012 - [JSOI2008] - 最大数maxnumber - 线段树 - 单点更新 - 区间查询最大
- bzoj1012: [JSOI2008]最大数maxnumber(线段树)
- BZOJ 1012: [JSOI2008]最大数maxnumber(线段树)
- BZOJ 1012 JSOI2008 最大数maxnumber 单调栈+二分 / 线段树
- 线段树——BZOJ1012/Luogu1198 [JSOI2008]最大数
- 【bzoj1012】【JSOI2008】【最大数】【maxnumber】【线段树】
- 【线段树】BZOJ1012 [JSOI2008]最大数maxnumber
- 【bzoj 1012】[JSOI2008]最大数maxnumber(线段树||st表)
- BZOJ 1012: [JSOI2008]最大数maxnumber 三种解法
- bzoj 1012: [JSOI2008]最大数maxnumber 线段树