洛谷Oj-P1198 [JSOI2008]最大数-线段树(单点修改)
2018-04-02 09:29
567 查看
问题描述:
现在请求你维护一个数列,要求提供以下两种操作:
1、 查询操作。
语法:Q L
功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值。
限制:L不超过当前数列的长度。(L>=0)
2、 插入操作。
语法:A n
功能:将n加上t,其中t是最近一次查询操作的答案(如果还未执行过查询操作,则t=0),并将所得结果对一个固定的常数D取模,将所得答案插入到数列的末尾。
限制:n是整数(可能为负数)并且在长整范围内。
注意:初始时数列是空的,没有一个数。
AC代码:
解决方法:
这道题和一般线段树不一样的地方是数列元素的个数未知,不存在初始化建树的操作,数列的元素是动态添加的。由于最多有m次修改,那么数列的元素最多有m个,于是数列的大小定为m。初始化数列的全部元素为0,动态添加元素可以转换为线段树的单点修改。
现在请求你维护一个数列,要求提供以下两种操作:
1、 查询操作。
语法:Q L
功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值。
限制:L不超过当前数列的长度。(L>=0)
2、 插入操作。
语法:A n
功能:将n加上t,其中t是最近一次查询操作的答案(如果还未执行过查询操作,则t=0),并将所得结果对一个固定的常数D取模,将所得答案插入到数列的末尾。
限制:n是整数(可能为负数)并且在长整范围内。
注意:初始时数列是空的,没有一个数。
AC代码:
long long st[800010]; void push_up(int node)//取较大值 { st[node] = max(st[node * 2],st[node * 2 + 1]); return; } void up_date(int node,int l,int r,int a,int b)//单点修改,元素a的值加上b { if(l == r)//到达了只代表一个元素的线段树结点(叶子结点) { st[node] += b; return; } else { int mid = (l + r) / 2; if(a <= mid)//如果在左边 up_date(node * 2,l,mid,a,b);//就去左边找 else//如果在右边 up_date(node * 2 + 1,mid + 1,r,a,b);//就去右边找 push_up(node); } return; } long long query(int node,int l,int r,int a,int b) { if(a <= l && r <= b)//完全包含,直到递归到完全包含为止 return st[node]; else { int mid = (l + r) / 2; long long ans = -inf;//初始化 if(a <= mid)//如果与左儿子重叠 ans = max(ans,query(node * 2,l,mid,a,b)); if(b >= mid + 1)//如果与右儿子重叠 ans = max(ans,query(node * 2 + 1,mid + 1,r,a,b)); return ans; } } int main() { int m,d; cin >> m >> d;//m个操作,对d取模 int sum_e = 0;//数列中元素的个数,同时也是新数应该放入的位置 int t = 0;//上一次查询的结果 for(int i = 1; i <= m; ++i) { char order; cin >> order; if(order == 'A') { sum_e++;//元素个数+1 int n; cin >> n; up_date(1,1,m,sum_e,(n + t) % d);//a[sum_e] = (n + t) % d } else { int l; cin >> l; if(l == 0)//不加一个点MLE一个点WA,加了AC { t = 0; cout << t << endl; continue; } t = query(1,1,m,sum_e - l + 1,sum_e); cout << t << endl; } } return 0; }
解决方法:
这道题和一般线段树不一样的地方是数列元素的个数未知,不存在初始化建树的操作,数列的元素是动态添加的。由于最多有m次修改,那么数列的元素最多有m个,于是数列的大小定为m。初始化数列的全部元素为0,动态添加元素可以转换为线段树的单点修改。
相关文章推荐
- [BZOJ] 1012 - [JSOI2008] - 最大数maxnumber - 线段树 - 单点更新 - 区间查询最大
- [JSOI2008] [洛谷P1198] 最大数|线段树80'|单调栈100'
- BZOJ 1012: [JSOI2008]最大数maxnumber【线段树单点更新求最值,单调队列,多解】
- P1198 [JSOI2008]最大数(线段树)
- 洛谷P1198 [JSOI2008]最大数(线段树)
- 线段树——BZOJ1012/Luogu1198 [JSOI2008]最大数
- 【线段树】【JSOI 2008】【bzoj 1012】最大数maxnumber
- BZOJ 1012 [JSOI2008]最大数maxnumber=听说是线段树
- 洛谷 P1198 BZOJ 1012 [JSOI2008] 最大数
- BZOJ_1012_[JSOI2008]最大数maxnumber_暴力?(线段树)
- bzoj1012: [JSOI2008]最大数maxnumber(线段树)
- BZOJ 1036 [ZJOI2008]树的统计Count (树链剖分)(线段树单点修改)
- Spoj 1716 Can you answer these queries III 线段树 单点修改 区间求最大子段和
- [BZOJ1012]JSOI2008 最大数|线段树|平衡树
- [BZOJ1012][JSOI2008]最大数maxnumber(线段树)
- P1198 [JSOI2008]最大数
- [JSOI2008]最大数 --线段树
- 最大值[JSOI2008] 洛谷1198 线段树
- [JSOI2008]最大数 线段树解法
- bzoj 1012: [JSOI2008]最大数maxnumber(线段树)