java 操作格子问题(线段树)
很久之前做过线段树的问题(操作格子),时间长了之后再次接触到,发现当初理解的不是很透彻,然后代码冗长,再遇到的时候发现自己甚至不能独立地完成这个问题。
所以算法这个东西啊,
第一,是要经常练习(我个人认为…每一个程序员都不应该不擅长算法…从今天开始,要常写博客!)。
第二,是一定要理解透彻,理解透彻并不是说到网上找到了解答,然后自己照着能够运行出来,这样是不够的!甚至不是说你看完了一个算法之后,完全不看他的解答,然后你自己写出来,这样也是不够的!
先贴题目:
有n个格子,从左到右放成一排,编号为1-n。
共有m次操作,有3种操作类型:
1.修改一个格子的权值,
2.求连续一段格子权值和,
3.求连续一段格子的最大值。
对于每个2、3操作输出你所求出的结果。
第一行2个整数n,m。
接下来一行n个整数表示n个格子的初始权值。
接下来m行,每行3个整数p,x,y,p表示操作类型,p=1时表示修改格子x的权值为y,p=2时表示求区间[x,y]内格子权值和,p=3时表示求区间[x,y]内格子最大的权值。
有若干行,行数等于p=2或3的操作总数。
每行1个整数,对应了每个p=2或3操作的结果。
1 2 3 4
2 1 3
1 4 3
3 1 4
3
对于20%的数据n <= 100,m <= 200。
对于50%的数据n <= 5000,m <= 5000。
对于100%的数据1 <= n <= 100000,m <= 100000,0 <= 格子权值 <= 10000。
下面贴代码:
//操作格子
#include<iostream>
#include<algorithm>
using namespace std;
struct GridNode{
int sum = 0;
int max = 0;
}segTree[400000];
int a[100001];
void build(int root, int start, int end){
//叶子
if (start == end){
segTree[root].sum = a[start];
segTree[root].max = a[start];
return;
}
int mid = (start + end) / 2;
build(2 * root, start, mid);
build(2 * root + 1, mid + 1, end);
//回溯更新结点
segTree[root].sum = segTree[2 * root].sum + segTree[2 * root + 1].sum;
segTree[root].max = max(segTree[2 * root].max, segTree[2 * root + 1].max); }
void update(int pos, int root, int start, int end, int x){
if (start == end){
segTree[root].max = x;
segTree[root].sum = x;
return;
}
int mid = (start + end) / 2;
if (pos <= mid){
update(pos, 2 * root, start, mid, x);
}
else{
update(pos, 2 * root + 1, mid + 1, end, x);
}
//回溯更新结点
segTree[root].sum = segTree[2 * root].sum + segTree[2 * root + 1].sum;
segTree[root].max = max(segTree[2 * root].max, segTree[2 * root + 1].max);
}
int querySum(int root, int nStart, int nEnd, int qStart, int qEnd){
if (qStart <= nStart && qEnd >= nEnd){
return segTree[root].sum;
}
int sum = 0;
int mid = (nStart + nEnd) / 2;
if (qStart <= mid)
sum += querySum(2 * root, nStart, mid, qStart, qEnd);
if (qEnd > mid)
sum += querySum(2 * root + 1, mid + 1, nEnd, qStart, qEnd);
return sum;
}
int queryMax(int root, int nStart, int nEnd, int qStart, int qEnd){
if (qStart <= nStart && qEnd >= nEnd){
return segTree[root].max;
}
int maxN = -1;
int mid = (nStart + nEnd) / 2;
if (qStart <= mid)
maxN = max(maxN, queryMax(2 * root, nStart, mid, qStart, qEnd));
if (qEnd > mid)
maxN = max(maxN, queryMax(2 * root + 1, mid + 1, nEnd, qStart, qEnd));
return maxN;
}
int main(){
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; i++){
cin >> a[i];
} build(1, 1, n);
for (int i = 0; i<m; i++){
int op, x, y;
cin >> op >> x >> y;
int resSum;
int resMax;
switch (op) {
case 1:
update(x, 1, 1, n, y);
break;
case 2:
resSum = querySum(1, 1, n, x, y);
cout << resSum << endl;
break;
case 3:
resMax = queryMax(1, 1, n, x, y);
cout << resMax << endl;
break; }
}
}
java 操作格子问题(线段树)的更多相关文章
- 【BZOJ 2333 】[SCOI2011]棘手的操作(离线+线段树)
2333: [SCOI2011]棘手的操作 Description 有N个节点,标号从1到N,这N个节点一开始相互不连通.第i个节点的初始权值为a[i],接下来有如下一些操作: U x y: 加一条边 ...
- 洛谷P4247 序列操作 [清华集训] 线段树
正解:线段树 解题报告: 传送门! 通过这题我get了一个神奇的,叫,线段树五问的东西hhhh 听起来有点中二但感觉真正做题的时候还是比较有用的,,,?感觉会让条理清晰很多呢,所以放一下QwQ →每个 ...
- 【BZOJ 2333 】[SCOI2011]棘手的操作(离线+线段树|可并堆-左偏树)
2333: [SCOI2011]棘手的操作 Description 有N个节点,标号从1到N,这N个节点一开始相互不连通.第i个节点的初始权值为a[i],接下来有如下一些操作: U x y: 加一条边 ...
- BZOJ2333 [SCOI2011]棘手的操作 【离线 + 线段树】
题目 有N个节点,标号从1到N,这N个节点一开始相互不连通.第i个节点的初始权值为a[i],接下来有如下一些操作: U x y: 加一条边,连接第x个节点和第y个节点 A1 x v: 将第x个节点的权 ...
- 【序列操作III】线段树
题目描述 给出序列 a1,a2,…an(0≤ai≤109),有关序列的四种操作: 1. al,al+1,…,ar(1≤l≤r≤n)加上 x(-103≤x≤103) 2. al,al+1,…,ar(1≤ ...
- 【序列操作I】线段树
题目描述 Lxhgww 最近收到了一个 01 序列,序列里面包含了 n(1≤n≤105)个数,这些书要么是 0,要么是 1,现在对这个序列有五种变换操作和询问操作:1. 0 a b ,把[a,b]区间 ...
- 2018.07.30 cogs2632. [HZOI 2016] 数列操作d(线段树)
传送门 线段树基本操作 区间加等差数列,维护区间和. 对于每个区间维护等差数列首项和公差,易证这两个东西都是可合并的,然后使用小学奥数的知识就可以切掉这题. 代码: #include<bits/ ...
- BZOJ4034 [HAOI2015]树上操作+DFS序+线段树
参考:https://www.cnblogs.com/liyinggang/p/5965981.html 题意:是一个数据结构题,树上的,用dfs序,变成线性的: 思路:对于每一个节点x,记录其DFS ...
- [BZOJ1858] [SCOI2010] 序列操作 解题报告 (线段树)
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1858 Description lxhgww最近收到了一个01序列,序列里面包含了n个数, ...
随机推荐
- python 库之lxml安装 坑一个
error: command 'C:\\Users\\Admin\\AppData\\Local\\Programs\\Common\\Microsoft\\Visual C++ for Python ...
- Highway Networks
一 .Highway Networks 与 Deep Networks 的关系 深层神经网络相比于浅层神经网络具有更好的效果,在很多方面都已经取得了很好的效果,特别是在图像处理方面已经取得了很大的突破 ...
- SGU180(树状数组,逆序对,离散)
Inversions time limit per test: 0.25 sec. memory limit per test: 4096 KB input: standard output: sta ...
- PE文件格式详解,第二讲,NT头文件格式,以及文件头格式
PE文件格式详解,第二讲,NT头文件格式,以及文件头格式 作者:IBinary出处:http://www.cnblogs.com/iBinary/版权所有,欢迎保留原文链接进行转载:) PS:本篇博客 ...
- python 多线程和多进程的区别 mutiprocessing theading
多线程可以共享全局变量,多进程不能.多线程中,所有子线程的进程号相同:多进程中,不同的子进程进程号不同. #!/usr/bin/python # -*- coding:utf-8 -*- import ...
- Jquery地图热点效果-鼠标经过弹出提示信息
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/ ...
- Javascript 面向对象编程—封装
前 言 Javascript是一种基于对象(object-based)的语言,你遇到的所有东西几乎都是对象.但是,它又不是一种真正的面向对象编程(OOP)语言,因为它的语法中没有class(类) ...
- checkValidity-表达验证方法。
调用该方法,可以显示对表单元素进行有效验证,返回值是boolean. 代码如下: <!DOCTYPE html> <html> <head> <meta ch ...
- 【转载】十条jQuery代码片段助力Web开发效率提升
文章转载自 51CTO http://www.51cto.com/ 原文链接:http://developer.51cto.com/art/201604/509093.htm原文摘要:JQuery是继 ...
- Django入门教程(二)
建议直接阅读末尾!!! Writing your first Django app, part 2 本节将设置数据库,创建您的第一个模型(model),并简单介绍Django自动生成的管理页面. 数据 ...